请考虑以下代码:
>>> colprint([
(name, versions[name][0].summary or '')
for name in sorted(versions.keys())
])
此代码的作用是按照versions
的升序打印字典keys
的元素,但由于value
是另一个排序列表,因此仅显示其<首先打印em> first 元素('max')。
由于我熟悉来自lisp的let
,我将上述内容重写为:
>>> colprint([
(name, package.summary or '')
for name in sorted(versions.keys())
for package in [versions[name][0]]
)]
你认为这会违反being Pythonic吗?可以改进吗?
注意:对于好奇,colprint
定义为here。
答案 0 :(得分:7)
为什么不利用元组?
colprint([(name, version[0].summary or '')
for (name, version) in sorted(versions.iteritems())])
或者,甚至
colprint(sorted([(name, version[0].summary or '')
for (name, version) in versions.iteritems()]))
另外,你可以考虑(在我的第一个例子中)删除[]
,因为这样你得到一个生成器而不是一个列表(可能有用也可能没用,因为我猜这个' ll打印整个数组,因此您不会保存任何评估。)
答案 1 :(得分:5)
在大多数情况下,我不会使用“棘手的条款”(或“let-equivalent”),但如果这是避免重复的自然方式,尤其是代价高昂的重复,我会这样做。 E.g。
xs = [(y, y*1.2, y-3.4) for z in zs for y in [somefun(z)] ]
对我来说比调用somefun
三次更好! - )所以,值得记住,即使可能不值得使用它不会消除重复。
答案 2 :(得分:4)
所以你使用“for y in [y]”代替“let x y”。
尝试用另一种语言模拟语言的语法绝不是一个好主意。我认为原始版本更清晰。
答案 3 :(得分:1)
正如Tordek所说,在这种情况下,您可以使用items()
或iteritems()
来避免此问题:
colprint(sorted((name, packages[0].summary or '')
for (name, packages) in versions.items()))
将排序移到外面是个不错的选择。
[请注意,items()
的使用稍微改变了排序顺序 - 它曾经是名称,并且按原始顺序解决了绑定(Python排序是稳定的),现在它的名称是通过摘要解决的联系。由于dict的原始顺序是随机的,新行为可能更好。]
但是对于其他用途(例如Alex Martelli的例子),“let”-alike可能仍然有用。
我也曾经发现for var in [value]
伎俩,但现在我发现它很难看。
一个更清晰的替代方案可能是理解/生成器的“管道”,使用“decorate / undecorate”技巧来传递元组中的附加值:
# You could write this with keys() or items() -
# I'm just trying to examplify the pipeline technique.
names_packages = ((name, versions[name][0])
for name in versions.keys())
names_summaries = ((name, package.summary or '')
for (name, package) in names_packages)
colprint(sorted(names_summaries))
或适用于Alex的例子:
ys = (somefun(z) for z in zs)
xs = [(y, y*1.2, y-3.4) for y in ys]
(您甚至不需要原始z
值,因此中间值不必是元组。)
有关“管道”技术的更有力的示例,请参阅http://www.dabeaz.com/generators/ ...
答案 4 :(得分:0)
您可以将排序移到最后以避免一些中间列表。
我觉得这看起来好一点:
colprint(sorted(
(name, version[0].summary or '')
for (name,version) in versions.iteritems())
))
Python3可以做得更好:
colprint(sorted(
(name, first_version.summary or '')
for (name,(first_version,*_)) in versions.items())
))