Python 字典迭代

3

我是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
由于字典是无序的,所以“3”的“第一次”出现是什么意思? - wim
3
变量名称为 dict 是个不好的主意,因为会遮蔽内置函数。 - wim
谢谢Wim。我不确定是否可能。有三个3的出现,我的意思是1:[“2”,“3”],在这个中,3第一次出现。 - Pujan
2
你应该定义一下你所说的“第一个”。字典本身没有固有的顺序。你是指dict[x]包含'3',其中x是最小值吗? - Vaughn Cato
2
@Pujan Srivastava:请更新问题并包含所有细节。长列表的评论是一件可怕的事情。您创建了这个问题,您可以更新它以使其变得完全清晰。 - S.Lott
7个回答

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()

编辑(根据您关于在列表中查找是字典项值的第一个“3”的评论进行更新) - 这应该可以工作:

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()

你应该在某处设置foundThree。 - wim
@wim 刚刚注意到我在评估后忘记将其设置为True了。谢谢! - chown
1
这很好。但是,True/False标志几乎总是会变成计数器。你应该考虑使用threeCount = 0threeCount += 1if '3' in val and threeCount == 0:,以便扩展处理更加优雅。 - S.Lott

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

1
你还可以记录元素出现的次数。使用字典来实现,并在每次出现时进行递增操作:
#!/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将按照dc的键排序的顺序包含3个字符串,然后只需迭代序列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...

我认为他正在寻找第一个包含“3”的列表,而不是按顺序排列的所有“3”。 - user648852

0
下面的代码片段将让你了解如何实现它。 这将在单线程执行环境中工作。
要获取更多信息,请查看Python文档和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的答案是更好的Pythonic方法。 - Anupam Saini
2
for i in range(len(obj)) 很少是合适的。在这里肯定不合适。 - S.Lott
@S.Lott,请分享正确的方法,因为我一直在使用相同的方法来迭代列表对象。顺便说一句,我最近开始使用Python工作,发现它非常适合创建后端任务和创建分析数据的脚本。 - Anupam Saini
for i in range(len(obj)): value = obj[i] === for value in obj: for i in range(len(obj)):value=obj[i] === for value in obj - S.Lott

0
假设“first”按字典键排序,那么这个方法可以工作:
>>> 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']]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接