"sep".join(list) ãæ°æã¡æªãçç±
list ãå¿
é 㧠separator ã¯ãªãã·ã§ã³ãªãã ãããlist ã receiver ã«ãªãã»ããã©ãèãã¦ãèªç¶ã ãããçç¥å¯è½ãª separator ã receiver ã«ããã»ããä¸èªç¶ã ã
str.join() å¦çã§ã®ç»å ´äººç©ã¯2人ãããé£çµæå(åºåãæå=separator)ãé£çµãããæååã®åã ã
ãã®äºã¤ãæ¯ã¹ãã¨ããé£çµãããæååã®åããæ å ±çã«éè¦ãªå ´åãã»ã¨ãã©ã ããããããå ã«æååã®åã主役ã§é£çµæåã¯ãªãã±ã¨èããã¨ããjoinã主役ã§ãªãé£çµæåå´ã®ã¡ã½ããã«ãªãä½ã¦ãã¢ãã¯ã«ã¤ãã¨ãªãã
','.join() がなぜキモイのか - methaneのブログ
ããããèãæ¹ãã§ãããã©ããã£ã¨åç´ã«èããã°ããã¨æããjoinããã¨ãã«ãlist (or iterable) ã¯å¿ é ã ãã©ãseparatorã¯ããã¾ã§ãªãã·ã§ã³ã§ãã£ã¦ãçç¥å¯è½ãªãã®ã ããã®çç¥å¯è½ãªãã®ãreceiverã«ãªã£ã¦ããæç¹ã§æ°æã¡æªãããã
ã§ããå¥ã®è¦ç¹ã§ãé£çµããå´ã¨ãããå´ãã¨ããããã«åé¡ããã¨ããåºåãæå join é£çµãããæåããç´ ç´ãªè½åæ ã§ããé£çµãããæåå (is) join(ed by) é£çµãããæåãã ã¨ç¡çãããªååæ ã«ãªãã®ã§ã''.join() ã®æ¹ãç´ ç´ã ã
ãåºåãæå join é£çµãããæåãã¯ç´ ç´ãªã®? æ®éã¯ãjoin A, B and C with separatorããããªãããªãSeparator ã£ã¦ä¸»èªã«ãªãã£ã?
Rubyã®å ´åã¯ãé åãè¦ç´ ãjoinãããã¨é åã主ä½ã¨ãªã£ã¦ããã®ã§ãå¾è ã®èãæ¹ã¯ãã«ããããªã®ã§ ã''.join() ããã¢ã¤ãã¨æã£ã¦ãã¾ã人ãå¤ãã
ãããèãããããããããªããã©ãåã« list (or iterable) ã¯å¿ é ã ãã© separator 㯠optional ã£ã¦ã ãã ã¨æããã
ä»åº¦ã¯ãjoin() ããæååã®åãé£çµãã¨ãã¦åããããé åã®è¦ç´ ãé£çµãã¨åããã®éãã
Pythonã«ã¨ã£ã¦ã¯ãæååã®åã®é£çµãé å(list)以å¤ã§ãiterableãªãã®ãªãä½ã§ãé£çµããããstr->unicodeã®ãããªæé»ã®åå¤æã¯ãã¦ããæ°å¤âæååã®ãããªæ示çãªåå¤æã¯ãããªãã
ãããä¸ä¾¿ã ãããã©ãããªã 'string'.join(iterable) ã¯è¦ç´ ãèªåçã« str() ãã¦æ¬²ããããu'uni'.join(iterable) ãªã unicode() ãã¦æ¬²ããã
ããã«å¯¾ãã¦ãRubyã®å ´åã¯ãé åã®è¦ç´ ã®é£çµãã§ã Array.to_s ã®ããæè»ãªãã¼ã¸ã§ã³çãªåå¨ãé£çµããéã«ã¯é åã®è¦ç´ ãåæã« to_s ããã
ãArray.to_s ã®ããæè»ãªãã¼ã¸ã§ã³çãªåå¨ãã£ã¦ä½ã ããããããªé¢¨ã«æã£ããã¨ã¯ä¸åº¦ããªããã
Rubyã®Array.joinãæååå°éã«ãªãã®ã¯ãæååã¯ãã使ãããç¹å¥ãã¨ããçºæ³ã ãã©ã
ããããªãã¨ããããã¯ãArray ã® join ããçµæã¨ãã¦æåå以å¤ã«èããããªãã¨ããæãã ãããã
Array.join()ã®æ»ãå¤ãæåå以å¤ã£ã¦ä½ãããããªã
Pythonã«ã¨ã£ã¦ã¯ãæ確ãªã¡ãªãããç¡ãéãç¹å¥ãæã¡è¾¼ãã®ã¯ãã¢ã¤ãã ãããããããPythonã«ã¯æååãåãè¾¼ã¿åã ã㧠str, unicode, bytes, bytearray ã®4ã¤ã(Python2.xã§ã¯strã¨bytesãã¨ã¤ãªã¢ã¹ã§ãPy3kã§ã¯strãunicodeã«ãªã£ã¦unicodeã¯ãªããªãã®ã§å®è³ª3ã¤)ããã®ãã¡ä¸ã¤ã ãããç¹å¥ãæ±ãããã®ã¯ããããä¸å¯è½ã ã
ãç¹å¥æ±ããã¨ããã®ã¯ä½ã®ãã¨ããã£ã¦ããã®ã ããããèªåçã« str() ãé©ç¨ãããã¨ããã£ã¦ããã®ããªã
ããããã ã¨ãã¦ããã¹ã¤ã«1ã¤ã ããç¹å¥æ±ãããå¿
è¦ãªãããªãããã
def join(iterable, sep=''): t = type(sep) return sep.join(t(x) for x in iterable) join([1, 2, 3], u'') #=> u'123' join(x*x for x in xrange(1,5)) #=> '14916' list.join = join # 注: å®éã«ã¯ã§ããªã
ã ããããä»ã ã£ã¦ 'str'.join(iterable) ã¯å¿ ã str ãè¿ããããããªããiterable ä¸ã« unicode ãæ··ãã£ã¦ãããããã separator ã str ã§ãæ»ãå¤ã¯ unicode ã«ãªã£ã¡ãããã ãããåãã«ã¼ã«ã join ã«é©ç¨ããã°ããã ããããããã°ãã1ã¤ã ããç¹å¥æ±ãããããªãã¦æè¦ã¯æ¶ãã¦ãªããªãã
## str.join() ã®çµæã¯å¿ ããã str ã§ã¯ãªãã ## (å¼æ°ã®åã«å½±é¿ãåãã) >>> ','.join(['A', u'B', 'C']) u'A,B,C' ## ããã¨åãã«ã¼ã«ã Array.join() ã§ã使ãã°ããã >>> ['A', u'B', 'C'].join(',') u'A,B,C'
å¹ççãªæååã®é£çµãå®è£ ããã«ã¯ãæååã®å é¨è¡¨ç¾ãç¥ãå¿ è¦ããããããã«å¯¾ãã¦ãæååã®åã®å ¥ãç© (Arrayç) ã«é¢ãã詳細ã¯ç¥ããªãã¦ãè¯ãã
ããã ãæååã¹ã£ããã® join ã¡ã½ããã Array ã®ã¡ã½ããã«ãªã£ã¦ããã®ã¯ãåå空éã大äºã«ããPythonistaããè¦ãã¨ãã¢ã¤ã
ãã㯠Java ã§ããã¨ããã® StringBuffer ã StringBuilder ã Python ãç¨æãã¦ããªããã¨ãåå ã ãããRuby ã®å ´åã¯æååãã®ãã®ã StringBuffer ã®æ©è½ãå ¼ãæãã¦ãããããæååã®å é¨è¡¨ç¾ãç¥ããªãã¦ãå¹çã®è¯ãæååã®é£çµãã§ããã
StringBuffer ç¸å½ã®æ©è½ãç¨æãã¦ããªã Python ã§ã¯ãå¹çã®ããæååé£çµãè¡ãªããã¨æã£ããæååã®å é¨æ§é ãç¥ããªãã¦ã¯ãªããããã®ããã« join ãæååã®ã¡ã½ããã¨ãªã£ã¦ããã®ã¯ç解ã§ãããããã Ruby ã§ã¯äºæ ãéããå¹çã®ããæååé£çµæ©è½ããã§ã«æååèªèº«ã«åãã£ã¦ããã®ã§ãArray ãä»ã®ã¯ã©ã¹ãæååã®å é¨æ§é ãç¥ãå¿ è¦ã¯å¥ã«ãªãã
Python ã§ã¯ join() ãæååã®ã¡ã½ããã§ããæ¹ãé½åããããã¨ã¯ç解ã§ããããåå空éããã¬ãã¨ããææã¯éãããããªãããªã
ããä¸ã¤ãPythonã 㨠iterable ãªãä½ã§ã join ã§ããã®ã«ãRubyã 㨠Array以å¤ã® Enumerable ã¯ä¸æ¦ Array ã«ãã¦ãããªã㨠join ã§ããªãã
ããããããããã¼ãRuby ã§ã¯ãªã㧠join ã Enumerable ã§ã¯ãªã Array ã®ã¡ã½ãããªãã ãããã
Enumerable#each() ã¯é çªãä¿è¨¼ããªãããã¨ããç¡éãæ±ããã¨ããããããã¨ãã説ãããããé çªãä¿è¨¼ããªãããããªãçç±ã¯ãªãããªãããjoin 㯠each ã®é çªã§é£çµãã¾ããã¨è¨ãåãã°ããã ããã ããã Enumerable#first ãããã®ã«ãé çªããã¬ãã¯é¢ä¿ãªãã ããã¾ãç¡éããã¬ãããã¨ã£ã¦ã¤ããçç±ã ããªããeach ãç¡éãæ±ã£ã¦ããå ´åãjoin ãå¼ã³åºãã¨æ»ã£ã¦ãã¾ãããã§ãããããEnumerable#collect() ã ã£ã¦æ»ã£ã¦ããªãã ãããã
ããã¯ããã¨è¦å¹çãæªããã ãã©ãå®ã¯Pythonã® ''.join ãåãåã£ã iterable ãã¿ãã«ããªã¹ãã§ãªãå ´åã¯ä¸æ¦ã¿ãã«ã«ãã¦ããå¦çãã¦ããã(stringobject.c ã® string_join ãè¦ã)
ã¤ã¾ã iterable ãç¡éãæ±ã£ã¦ããå ´å㯠tuple ã«å¤æã§ããªãã¦ã¨ã©ã¼ã«ãªãããã ãããRuby ãããã¨åãä»æ§ã§ãããã Enumerable#join ãå®è£ ãã¦ã»ããã
æååã¯å é¨ã§ã¯ã·ã³ãã«ã«æååãã¡ã¢ãªä¸ã§é£ç¶ãã¦ããå®è£ ãªã®ã§ããã®ã¡ã¢ãªã確ä¿ããçºã«ã¯ã¾ãé£çµå¾ã®ãµã¤ãºãè¨ç®ããããããã¨å¦ç㯠2-pass ã«ãªããiterableã ã¨ä¸ååæããå¤ãããä¸ååæã§ãããã©ããå¤ããªãã®ã§ãä¸æ¦ã·ã¼ã±ã³ã¹åã«ãã¦ããå¿ è¦ãåºã¦ããããã ããªã®ã§ããªã¹ããã軽éãªã¿ãã«ãåå¨ããªãRubyã§ã¯ãArrayããjoinã§ããªãã¦ãããã©ã¼ãã³ã¹ä¸ã®å¶ç´ã«ã¯ãªããªãã
ãã£ããæ¸ããããã«ãStringBuffer ç¸å½ã®æ©è½ãããã°ããã¯ãã»ã©å¤§ããªåé¡ã«ã¯ãªããªãã
ä½è«ã ãã©ãJava ã® StringBuffer ã¯ä½ææã«å é¨é åã®å¤§ãããæå®ã§ãããã©ãRuby ã® String ã¯ãããã§ããªããã ããããããã§ããã¨ãeRuby ãã¡ãã£ã¨ã ãããã©ã¼ãã³ã¹ãæ¹åã§ãããã ãã©ã
ããã©ã¼ãã³ã¹ã®åé¡ãç¡ãã¨ããã¨ããã¨ã¯ä½¿ãåæã®åé¡ã ãPythonã®å ´åãç°¡åã«iteratorãä½ãããã®yieldæãç¨æããã¦ãããã¡ã¢ãªä½¿ç¨éãæ°ã«ãã¦é »ç¹ã« iterator ã使ãã
Python ã® yield æ㯠generator ãä½æããããããã㯠generator ã®ãã¨ã念é ã«ããã¦ãããã ã¨æããã©ããã㯠Ruby ã§ã¯ Enumerator ã«ç¸å½ãã(ãã?)ãã ããå¥ã« Python ã Ruby ã大ããªéãã¯ãªãã¨æã (æ段ã¯éã£ã¦ãç®çã¯ã»ã¼ä¸ç·ã ãã) ã
ã¾ããã·ã¼ã±ã³ã¹åãã¤ã³ã³ããåãªåãè¾¼ã¿åãä¸ã¤ã§ã¯ç¡ãããªã®ã§ããªã¹ããç¹å¥æ±ãããæåãç¡ããåã®æ±ç¨å㯠iterator ã ãã ãã join ã iterator ãåãåãã
ããã«å¯¾ãã¦ãRubyã ã¨ã¡ã¢ãªå¹çã¯ãã¾ãæ°ã«ãããã³ãã³ä¸æArrayãä½ããArrayã®ã¡ã½ãããã§ã¼ã³ãä½ã£ã¦ãã¢ãã¤ã¤ã¨æ¦ã¶ãRubyã«ã¨ã£ã¦Arrayã¯ç¹å¥ã§ãããåã®æ±ç¨å㯠Array ã ãArray以å¤ãjoinãããã£ããã to_a.join ããã°è¯ãã
Python ã® sequence ã¯ä¸ç¨®é¡ãããªããã©ãããããããªã Ruby ã® Enumerable ãä¸ç¨®é¡ã§ã¯ãªã*1ãPython ã§ã¯ itrator ã使ã£ã¦ç¹°ãè¿ããæ½è±¡åãã¦ãã¦ãRuby ã§ã¯ Enumerable ã使ã£ã¦æ½è±¡åãã¦ãããããæ¹ã¯éããã©ãã©ã¡ããç¹°ãè¿ãããã¾ãæ½è±¡åãã¦ãããã¨ã«å¤ããã¯ãªãã
å ã®æç« ãæ¸ãã人ãã©ãã ã Ruby ãç解ãã¦ãããã¯ããããªããã©ããRubyã«ã¨ã£ã¦Arrayã¯ç¹å¥ãã£ã¦ããã®ã¯èª¤è§£ãããªãã®ããªãRuby ã«ã¯ Enumerale#join ããªããã¨ãæ¹å¤ãããªãæ£ããã¨æããã©ãä¸ã®æç« ãè¦ãéã Python ã® iterable ã«ç¸å½ãããã®ã Ruby ã§ã¯ Array ãããªããããªæ¸ãæ¹ããã¦ãããããã¯æ£ããèªèã§ã¯ãªãã
ãã®æåã®éãã¯ãäºãã«ç解ãã«ãããPythonista ããè¦ãã¨ãArrayããjoinã§ããªããªãã¦ãã¢ã¤ãããRubyistããè¦ãã¨ãArrayã§ä½ãæªããã«ãªã£ã¦ãã¯ãçµè«ã¯ã§ãªãã
éãã¨æããªãã
Python ã«ããã¦ã(a) join ã iterable ã®ã¡ã½ããã§ã¯ãªãçç±ã¨ã(b) join ã str ã®ã¡ã½ããã§ããçç±ã¨ã¯å¥ã
ã«èããã»ããããã¨æãã
(a) ã«ã¤ãã¦ã ãã©ãPython ã§ã¯ iterable ã«å¯¾ããæä½ã¯ãããå¼æ°ã¨ããé¢æ°ã§å®ç¾©ããã»ããèªç¶ã§ãããiterable ãªãªãã¸ã§ã¯ãã®ã¡ã½ããã¨ãã¦ã¯å®ç¾©ãã«ããã¨ããã ãã®ãã¨ã
ã¾ã Ruby ãã説æããã¨ãRuby ã§ã¯ Enumerable ã使ã£ãå®è£
ç¶æ¿ãã§ãããããiterable ãªãã®ã«å¯¾ããæä½ã¯ Enumerable ã®ã¡ã½ããã¨ãã¦å®ç¾©ãããã¨ãã§ãããããããã°ãEnumerable ã include ããã¯ã©ã¹ã¯ãã¹ã¦åãã¡ã½ãããå
±æã§ããã
ããã Python ã¯å¤éç¶æ¿ãå®è£
ãã¦ããã®ã«ãRuby ã® Enumerable ã«ç¸å½ããæ½è±¡ã¯ã©ã¹ãç¨æãã¦ããªã*2ãã ãã iterable ãªãã®ãæä½ããã¡ã½ãããä½ããã¨æã£ããããã¹ã¦ã® iterable ãªã¯ã©ã¹ãã¨ã«åå¥ã«å®ç¾©ããªãã¨ãããªããããã¯ã©ãèãã¦ãã¾ããã®ã§ãPython ã§ã¯ãiterable ãªã¯ã©ã¹ã®ã¡ã½ãããã§ã¯ãªãã¦ãiterable ãå¼æ°ã«ã¨ãé¢æ°ããå®ç¾©ãããããªãã
ã¤ã¾ããjoin ã str ã®ã¡ã½ããã§ããã¹ããã©ããã¯å¥ã«ãã¦ãjoin ã list ã®ã¡ã½ããã«ãããã¨ã¯ Python ã§ã¯è¦ããããããããªããtuple ã generator ãªã©ãã¹ã¦ã® iterable ã§åãå®è£
ãç¨æããªãããããªãã
(b) ã«ã¤ãã¦ã¯ããã§ã«æ¸ããã¦ããããã«ãå¹çã®ããæååçµåã¯æååã®å é¨æ§é ãç¥ããªãã¨ãããªããããã¨ããçç±ãåå説å¾åãæã£ã¦ãããã§ãããã¯ããã¾ã§ StringBuffer ç¸å½ã®æ©è½ãæä¾ã§ãã¦ããªãã¨ããã®ãèæ¯ã«ããããã§ããããããæä¾ãããã° join(iterable, sep) ã®ãããªé¢æ°ã§ãæ§ããªãã
çµå±ã¯ãPython 㧠'str'.join(iterable) ã¨ãªã£ã¦ããã®ã¯ãããã Python ã®ä»æ§ã§ã¯åççã¨ããã ãã ãããéã«è¨ã㨠iterable.join('str') 㯠Python ã«ã¨ã£ã¦é½åãæªãã£ããã¨ããã ããããã¦ãã®é½åã®æªã㯠Ruby ã§ã¯å½ã¦ã¯ã¾ããªããããRuby ã§ã¯ list.join('str') ã§ç¹ã«åé¡ã¯ãªãã
åé¡ã¯ãªããã 'str'.join(list) ã§ã list.join('str') ã§ã Ruby ãªãã©ã¡ãã§ãå¯è½æ§ãããããã ãããªãã¸ã§ã¯ãæåçã«èããã° list.join('str') ã ãããçç±ã¯ãã§ã«æ¸ããããã«ãçç¥å¯è½ãª separator ã receiver ã«æ¥ãã®ã¯ä¸èªç¶ã ãããå¿ é è¦ç´ ã§ãã list ã receiver ã«ããã»ãã極ãã¦èªç¶ãªèãã
Python ã®ä»æ§ä¸åççãã©ããã¨ãã話ã¨ãããããªãã¸ã§ã¯ãæåã¨ãã¦èªç¶ãã©ããã¨ãã話ã¯å¥ãPython ã§ã¯ 'str'.join(iterable) ã®ã»ããåççãªãã¨ã¯ååç´å¾ã§ãããããªãã¸ã§ã¯ãæåã¨ãã¦ã¯ä¸èªç¶ãã©ã¡ããã¨ããã¨é¢æ°çã»æç¶ãçãªèã*3ã
*1:ããæ£ç¢ºã«ããã¨ãEnumerable ã¢ã¸ã¥ã¼ã«ã¯ã²ã¨ã¤ãããªããã©ããã include ããã¯ã©ã¹ã¯ä¸ç¨®é¡ã§ã¯ãªãã¨ãããã¨ã
*2:Python ã¯ãã£ããå¤éç¶æ¿ãå®è£ ãã¦ãããã ãããEnumerable ã«ç¸å½ããæ½è±¡ã¯ã©ã¹ãç¨æãã¦ããã¦ããããããªãã®ã ããæ´å²çãªçµç·¯ã¨ãlistãã¯ã©ã¹ãããªãä»æ§ã¨ãå®è£ ä¸ã®é½åã¨ããããããããã ããã
*3:ãããæªãã¨ããããã§ã¯ãªãã