2010-05-03 2 views
1

У меня есть этот список:Python итератора вопрос

names = ['john','Jonh','james','James','Jardel'] 

Я хочу цикл по списку и обрабатывать последовательные имена с регистрозависимости матча в одной и той же итерации. Поэтому на первой итерации я бы сделал что-то с «Йорном» и «Джоном», и я хочу, чтобы следующая итерация начиналась с «james».

Я не могу придумать, как это сделать, используя цикл Python for, любые предложения?

+0

Что бы вы сделали в случае, если имена не последовательны, т.е. '[" jo "," Jim "," jim "," Jo "]'? – OscarRyz

+1

Ваше второе имя - Джон. Полагаю, это опечатка, и это должен быть Джон? – extraneon

+0

Лично я бы создал набор имен, все нижние обсаженные, тем самым удаляя двойники и при необходимости заглавные буквы. Но это может не соответствовать вашим требованиям. – extraneon

ответ

6

Это будет один для itertools.groupby, который группирует последовательные равные элементы из списка или другого итерабельного. вы можете указать функцию для сравнения, так что в вашем случае одно и то же имя в разных случаях все равно можно считать одним и тем же.

for k, g in itertools.groupby(names, lambda s: s.lower()): 
    # Example: in the first iteration: 
    # k = "john" 
    # g = an iterator over ["john", "John"] 
    # Process them as you like 
+0

Как использовать g var? Я попытался распечатать его, но я получаю это: Я, очевидно, noob в python, поэтому, пожалуйста, не ненавидите меня :) – hdx

+0

Это потому, что это объект итератора. Вы можете использовать его в цикле for или в понимании списка (например, '[name for name in g]'), и вы получите имена из него, но если вы попытаетесь использовать его без итерации по нему, это будет просто показывается как итератор, как вы видели. Чтобы распечатать список имен, вы можете использовать 'print list (g)', который преобразует его в список перед печатью. –

+1

'g' является итератором над элементами в текущей группе. Вы можете перебирать его в цикле 'for' или в понимании списка или превращать его в список с помощью' list (g) '. Одна из возможных вещей - распечатать имена в текущей группе, разделенные запятыми: print '','.join (g) ', который работает, потому что метод' join' работает с любым итерабельным. –

2
names = ['john','John','james','James'] 
for name, capitalized_name in zip(names[::2], names[1::2]): 
    print name, capitalized_name 

Обратите внимание, что для правильной работы вам требуется ровное количество элементов.

Или (возможно, лучше, трудно сказать, с небольшим количеством контекста) использовать set, чтобы отфильтровать список содержит только уникальные имена (обратите внимание, что это теряет порядка):

>>> names = ['john','John','james','James','Jardel'] 
>>> unique_names = set([x.lower() for x in names]) 
>>> for unique_name in unique_names: 
...  print unique_name 
... 
jardel 
james 
john 
0

Вы могли бы просто использовать while цикл :

i = 0 
while i < len(names): 
    # compare names[i] with names[i + 1] 
    i = i + 2 # or + 1 if names not equal, for example 

Или вы ищете что-то более активное участие?

0

Как вы итерации через цикл, вы можете попробовать отслеживать предыдущее имя в списке. В то же время, когда вы собираетесь хранить имена, вы можете сделать вызов lower() или capitalize(), чтобы форматирование каждого имени было согласованным, чтобы вы могли легче сравнивать их.

например.

first = True 
prev= "" 
for name in names: 
    if first:       #First iteration 
     prev = name.lower()   #Need to get the first elem 
     do_something_to(curr) 
     first = False 
    else: 
     if prev == name.lower(): 
      print "do nothing" 
     else: 
      do_something_to(curr) 
     prev = name.lower() 

Не может быть самым эффективным, но работает.

0

Мои $ 0,02:

def byPairs(li): 
    for i in xrange(1, len(li), 2): 
     yield (li[i-1], li[i]) 

for a,b in byPairs(names): 
    if a.lower()==b.lower(): 
     doSomething(a,b) 

Я не уверен, что понял вопрос точно; Что вы пытаетесь достичь?