2011-09-28 2 views
3

Я новичок в Python.Словарь Iteration Python

Словарь имеет несколько значений.

dc = {1:['2', '3'], 2:['3'], 3:['3', '4']} 

Если вы повторяете «dc», вы обнаружите, что есть три вхождения «3». Первое вхождение находится в 1: ['2', '3']. Я хотел бы перебрать Словаре так что

if first occurrence of '3' occurs: 
    dosomething() 

else occurrence of '3' afterwards:#i.e. 2nd time, 3rd time.... 
    dosomethingelse() 

Как я могу сделать это в Python

Спасибо.

+4

Поскольку dict не заказан, что вы подразумеваете под «первым» появлением «3»? – wim

+3

стр. Именование вашей переменной 'dict' - плохая идея, потому что вы затеняете встроенный – wim

+0

Спасибо Wim. Я не уверен, что это возможно. Есть три случая из 3, я имею в виду 1: ['2', '3'] в этом, 3 появляется 1 раз –

ответ

1

Вы также можете следить за тем, как элемент был замечен. Используйте Dict для этого, и приращения с каждым визированием:

#!/usr/bin/python 

dc = {3:['3', '4'], 1:['2', '3'], 2:['3']} 
de={} 

def do_something(i,k): 
    print "first time for '%s' with key '%s'" % (i,k) 

def do_somethingelse(i,j,k): 
    print "element '%s' seen %i times. Now with key '%s'" % (i,j,k) 

for k in sorted(dc): 
    for i in dc[k]: 
     if i not in de: 
      de[i]=1 
      do_something(i,k) 
     else: 
      de[i]+=1 
      do_somethingelse(i,de[i],k) 

Как уже говорили другие, словари не имеют тот же порядок, обязательно в качестве вставки или коды листинга. Вы можете просто отсортировать ключи (с sorted(dc)), чтобы различать «первый» и последующий, если это то же самое, что и порядок сортировки. Этот метод легко распространяется на «do_somthing» на основе того, как много раз, когда предмет был замечен.

Выход:

first time for '2' with key '1' 
first time for '3' with key '1' 
element '3' seen 2 times. Now with key '2' 
element '3' seen 3 times. Now with key '3' 
first time for '4' with key '3' 

В качестве альтернативы:

r=[] 
for k in sorted(dc): 
    print dc[k] 
    if '3' in dc[k]: 
     r.append("'3' number {} with key: {}".format(len(r)+1,k)) 

производит:

["'3' number 1 with key: 1", "'3' number 2 with key: 2", "'3' number 3 with key: 3"] 

Список r будет иметь 3 строки в том порядке, что ключи dc сортируют в , затем просто перебираем последовательность r.

И если вы просто ищете для «первого» 3 затем в покое, вы можете использовать список понимание:

>>> l=[i for sub in [dc[k] for k in sorted(dc)] for i in sub if i == '3'] 
>>> l 
['3', '3', '3'] 
>>> l[0] 
'3' 
>>> l[1:] #all the rest... 
+0

Я думаю, что он ищет первый список, содержащий «3», а не все «3» в порядке сортировки ... –

0

Ниже приведен фрагмент кода, который даст вам представление о том, как это сделать. Это будет работать в среде с одним потоком.

Для получения дополнительной информации начинается в питоне документации и Dive Into Python

firstInstance = False 
for k in mydict.keys(): 
    obj = mydict.get(k) 
    for i in range(len(obj)): 
    value = obj[i] 
    if value == 3 and firstInstance: 
     doSomething() 
     firstInstance = True 
    else: 
     doSomethingElse() 
+1

Это даст вам представление о том, как это сделать, если вы пришли со стороны Java. Ответ @ chown - лучший пифонический подход. –

+2

'для i в диапазоне (len (obj))' редко бывает подходящим. Это, конечно, не уместно. –

+0

URL-адрес должен быть http://diveintopython.org – artdanil

4

Предполагая, что значения в Словаре являются списками:

foundThree = False 
for key, val in dc.items(): 
    if '3' in val and not foundThree: 
     foundThree = True 
     # doSomething() 
    elif '3' in val: 
     # doSomethingElse() 
    else: 
     # doAnotherThing() 

Edit (обновление для ваших комментариев по поводу нахождения первого '3' в списке, который является значением элемента dict) - это должно работать:

for key, val in dc.items(): 
    foundThree = False 
    for n in val: 
     if n == '3' and not foundThree: 
      foundThree = True 
      # doSomething() 
     elif n == '3': 
      # doSomethingElse() 
     else: 
      # doAnotherThing() 
+0

you должен установить findThree где-то. – wim

+0

@wim Только что заметил, что я забыл установить его в True после его оценки. Благодаря! – chown

+1

Это хорошо. Но. Истинные/ложные флаги почти всегда превращаются в счетчики. Вы должны рассмотреть возможность использования 'threeCount = 0'; 'threeCount + = 1' и' if '3' в val и threeCount == 0: ', так что расширение обрабатывается более изящно. –

3

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

Вы можете сделать это с помощью:

list[1:] 

Например:

>>> 3 in [1,2,4,5][1:] 
False 
>>> 3 in [3,1,2,4][1:] 
False 
>>> 3 in [1,2,3,4][1:] 
True 

Вот то, что должно работать:

dc = {1:['2', '3'], 2:['3'], 3:['3', '4']} 

def dosomething(): print 'something' 

def dosomethingelse(): print 'something else' 

for key,value in dc.items(): 
    if value[0] == '3': 
    dosomething() 
    elif '3' in value[1:]: 
    dosomethingelse() 
3
dict_ = {1:['2', '3'], 2:['3'], 3:['3', '4']} 

def dosomething(): 
    print 'doing something' 

def dosomethingelse(): 
    print 'doing something else' 

three_handler = dosomething 
for v in dict_.values(): 
    for three in [x for x in v if x == '3']: 
    three_handler() 
    three_handler = dosomethingelse 

Выход:

doing something 
doing something else 
doing something else 
2

Вот альтернатива, которая не использует оператор if, чтобы проверить, является ли 3 первым вхождением.

d = {1:['2', '3'], 2:['3'], 3:['3', '4']} 

def doSomething(): 
    print('ds') 

def doSomethingElse(): 
    print('dse') 

for key,value in d.iteritems(): 
    do = doSomething 
    for item in value: 
     if item == '3': 
     do() 
     do = doSomethingElse 
0

Предполагая, что «первый» как отсортировано по ключам словаря, это работает:

>>> dc = {1:['2', '3'], 2:['3'], 3:['3', '4']} 
>>> [dc[k] for k in sorted(dc) if '3' in dc[k]][0] 
['2', '3'] 
>>> [dc[k] for k in sorted(dc) if '3' in dc[k]][1:] 
[['3'], ['3', '4']]