2013-03-18 3 views
0

У меня есть строка пар ключ-значение, которые, к сожалению, разделены одним и тем же символом. Есть ли способ «просто разбить» его на список кортежей, не используя лямбда?разделите строку на список кортежей?

Вот что у меня есть:

Moscow|city|London|city|Royston Vasey|vilage 

Что я хочу:

[("Moscow","city"), ("London", "city")....] 
+0

Я попытался написать функцию, которая разделяет строку разделителями, а затем выполняет итерацию по ней и дает два следующих элемента в кортеже. – Ibolit

+3

@ Иболит вы можете ** показать **, что вы пробовали в своем вопросе? – Neal

ответ

6
def group(lst, n): 
    for i in range(0, len(lst), n): 
     val = lst[i:i+n] 
     if len(val) == n: 
      yield tuple(val) 

a = 'Moscow|city|London|city|Royston Vasey|vilage' 
list(group(a.split('|'), 2)) 

Выход [('Moscow', 'city'), ('London', 'city'), ('Royston Vasey', 'vilage')]

10

Это довольно просто один действительно ...

первый, разделить строку на '|' затем zip каждый другой элемент вместе:

data = s.split('|') 
print zip(data[::2],data[1::2]) 

В Python3, вам нужно: print(list(zip(data[::2],data[1::2]))

7
s = 'Moscow|city|London|city|Royston Vasey|vilage' 

it = iter(s.split('|')) 
print [(x,next(it)) for x in it] 
+3

Для соображений форвардной совместимости, вероятно, лучше поощрять 'next (it)', а не 'it.next()'. – DSM

+0

@ DSM OK, спасибо. Более того, '' next (it) '' более ясен. Но что вы подразумеваете под совместимостью froward? Относительно перехода на Python 3? – eyquem

+1

@eyquem, yes '.next' становится' .__ next__' в соответствии с другими методами, такими как '__str__' и' __len__' и т. Д. –

4

Для python2

>>> s = "Moscow|city|London|city|Royston Vasey|vilage" 
>>> zip(*[iter(s.split('|'))]*2) 
[('Moscow', 'city'), ('London', 'city'), ('Royston Vasey', 'vilage')] 

Python3 просто нужно list(zip(...)) конечно

+0

Умный, если тонкий . (+1) – NPE

+0

@NPE - это почти прямо где-то в документации по itertools. В конечном итоге это становится полезным иногда. – mgilson

+0

I +1, но это решение радует меня только на 3/4, потому что после создания списка '' s.split ('|') '' и создания итератора '' iter (s.split ('|')) '', создается еще один повторяющийся повтор одного итератора, тогда ему нужно дополнительная распаковка параметров «на лету» zip – eyquem

1

Вы мог бы использовать city, status, remaining = s.split("|", 2) и некоторый рекурсивный метод city_split(s) для достижения того, чего вы хотите.

+0

@Ibolit. Вы должны знать, что если в цепочке извлекается N кортежей, это решение создает строки N-1 с именем '' Остальные'', не имеющие реального оправдания, поскольку есть другие способы обойтись без этого. – eyquem

Смежные вопросы