2017-02-07 4 views
4

В Python, я могу цикл через 2 списков одновременно извлекать ngrams как таковые:Как выполнить итерацию с распаковкой zip (* list) в Julia?

>>> s = 'the lazy fox jumps over the brown dog' 
>>> list(zip(*[s[i:] for i in range(2)])) 
[('t', 'h'), ('h', 'e'), ('e', ' '), (' ', 'l'), ('l', 'a'), ('a', 'z'), ('z', 'y'), ('y', ' '), (' ', 'f'), ('f', 'o'), ('o', 'x'), ('x', ' '), (' ', 'j'), ('j', 'u'), ('u', 'm'), ('m', 'p'), ('p', 's'), ('s', ' '), (' ', 'o'), ('o', 'v'), ('v', 'e'), ('e', 'r'), ('r', ' '), (' ', 't'), ('t', 'h'), ('h', 'e'), ('e', ' '), (' ', 'b'), ('b', 'r'), ('r', 'o'), ('o', 'w'), ('w', 'n'), ('n', ' '), (' ', 'd'), ('d', 'o'), ('o', 'g')] 
>>> list(map(''.join, zip(*[s[i:] for i in range(2)]))) 
['th', 'he', 'e ', ' l', 'la', 'az', 'zy', 'y ', ' f', 'fo', 'ox', 'x ', ' j', 'ju', 'um', 'mp', 'ps', 's ', ' o', 'ov', 've', 'er', 'r ', ' t', 'th', 'he', 'e ', ' b', 'br', 'ro', 'ow', 'wn', 'n ', ' d', 'do', 'og'] 

В Джулии, я мог бы сделать подобные шаги, но я не уверен, как собрать их, как, как я сделал с Python.

Сначала я мог бы генерировать 2 списка, который должен повторяться одновременно, поэтому вместо Python [s[i:] for i in range(2)] в Джулии:

> s = "abc def ghi lmnopq" 
> [s[i:end] for i in range(1,2)] 
2-element Array{String,1}: 
"abc def ghi lmnopq" 
"bc def ghi lmnopq" 

И перебирать их одновременно, я мог бы сделать это:

> c1, c2 = [line[i:end] for i in range(1,2)] 
> [i for i in zip(c1, c2)] 
> [join(i) for i in zip(c1, c2)] 

Есть ли распаковочный механизм, как zip(*list) в Julia? Если да, то как избежать создания c1, c2 до последнего понимания списка в Julia?

ответ

6

Эквивалентная операция называется splatting в Julia и представлена ​​обратным эллипсисом. Вот грубые транслитерации кода Python:

julia> s = "the lazy fox jumps over the brown dog"; 
julia> collect(zip([s[i:end] for i in 1:2]...)) 
36-element Array{Tuple{Char,Char},1}: 
('t', 'h') 
('h', 'e') 
('e', ' ') 
(' ', 'l') 
('l', 'a') 
('a', 'z') 
⋮ 

julia> map(join, zip([s[i:end] for i in 1:2]...)) 
36-element Array{String,1}: 
"th" 
"he" 
"e " 
" l" 
"la" 
"az" 
⋮ 

Обратите внимание, что функция range не делать то, что вы думаете, что делает ... и это редко. Диапазоны обычно строятся с использованием синтаксиса двоеточия start:stop.

Вы также должны быть осторожны, поскольку строки Юлии индексируются байтовыми смещениями, поэтому использование 1:2 будет ломаться с строкой unicode. Вместо этого я просто напишу аргументы zip и воспользуюсь drop, чтобы пропустить первый символ:

collect(zip(s, drop(s, 1))) 
map(join, zip(s, drop(s, 1))) 
+0

Прохладный! Спасибо @MattB !! – alvas