这是我的问题:我在 python 中有一个字典,例如:
a = {1:[2, 3], 2:[1]}
我想输出:
1, 2
1, 3
2, 1
我正在做的是
for i in a:
for j in a[i]:
print i, j
那么有没有更简单的方法可以避免在这里出现两个循环,或者它已经是最简单的方法了?
你拥有的代码和它得到的一样好。一个小的改进可能是在外部循环中迭代字典的项目,而不是进行索引:
for i, lst in a.items() # use a.iteritems() in Python 2
for j in lst:
print("{}, {}".format(i, j))
如果您想避免显式的 for 循环,可以使用列表推导的几种替代方法。
# 1 方法
# Python2.7
for key, value in a.iteritems(): # Use a.items() for python 3
print "\n".join(["%d, %d" % (key, val) for val in value])
# 2 方法- 一种更奇特的列表推导方式
print "\n".join(["\n".join(["%d, %d" % (key, val) for val in value]) for key, value in a.iteritems()])
两者都会输出
1, 2
1, 3
2, 1
请记住,在 Python 中Readability counts.
,理想情况下,@Blckknght 的解决方案是您应该期待的,但只是从技术上将您的问题视为 POC,您可以将表达式重写为单个循环,这是一个解决方案。
但是需要注意的是,如果你想让你的代码可读,请记住Explicit is better than implicit.
>>> def foo():
return '\n'.join('{},{}'.format(*e) for e in chain(*(izip(cycle([k]),v) for k,v in a.items())))
>>> def bar():
return '\n'.join("{},{}".format(i,j) for i in a for j in a[i])
>>> cProfile.run("foo()")
20 function calls in 0.000 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <pyshell#240>:1(foo)
5 0.000 0.000 0.000 0.000 <pyshell#240>:2(<genexpr>)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
10 0.000 0.000 0.000 0.000 {method 'format' of 'str' objects}
1 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects}
1 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects}
>>> cProfile.run("bar()")
25 function calls in 0.000 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <pyshell#242>:1(bar)
11 0.000 0.000 0.000 0.000 <pyshell#242>:2(<genexpr>)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
10 0.000 0.000 0.000 0.000 {method 'format' of 'str' objects}
1 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects}