我几次遇到这个问题,似乎无法找到一个简单的解决方案.说我有一个字符串
string = "a=0 b=1 c=3"
Run Code Online (Sandbox Code Playgroud)
我想将其转换为字典,其中a,b和c是键,0,1和3是它们各自的值(转换为int).显然我可以这样做:
list = string.split()
dic = {}
for entry in list:
key, val = entry.split('=')
dic[key] = int(val)
Run Code Online (Sandbox Code Playgroud)
但我真的不喜欢循环,看起来很简单,你应该能够将它转换为某种列表理解表达式.这适用于稍微简单的情况,其中val可以是一个字符串.
dic = dict([entry.split('=') for entry in list])
Run Code Online (Sandbox Code Playgroud)
但是,我需要动态地将val转换为int,并且做这样的事情在语法上是不正确的.
dic = dict([[entry[0], int(entry[1])] for entry.split('=') in list])
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:有没有办法消除使用列表理解的for循环?如果没有,是否有一些内置的python方法可以为我做到这一点?
python string dictionary list-comprehension generator-expression
我想确定列表是否包含某个字符串,所以我使用生成器表达式,如下所示:
g = (s for s in myList if s == myString)
any(g)
Run Code Online (Sandbox Code Playgroud)
当然我想内联这个,所以我这样做:
any((s for s in myList if s == myString))
Run Code Online (Sandbox Code Playgroud)
然后我认为单个parens会更好看,所以我尝试:
any(s for s in myList if s == myString)
Run Code Online (Sandbox Code Playgroud)
并不是真的期待它的运作.惊喜!它呢!
那么这个合法的Python还是我的实现允许的东西?如果它是合法的,这里的一般规则是什么?
我有时会看到这种事:
(k for k in (j for j in (i for i in xrange(10))))
Run Code Online (Sandbox Code Playgroud)
现在这真的让我的大脑弯曲了,我宁愿不以这种方式呈现.
是否有任何用例,或使用这些嵌套表达式的例子,它比嵌套循环更优雅,更可读?
编辑:感谢您简化此方法的示例.这实际上并不是我要求的,我想知道是否有任何优雅的时刻.
以下测试失败:
#!/usr/bin/env python
def f(*args):
"""
>>> t = 1, -1
>>> f(*map(lambda i: lambda: i, t))
[1, -1]
>>> f(*(lambda: i for i in t)) # -> [-1, -1]
[1, -1]
>>> f(*[lambda: i for i in t]) # -> [-1, -1]
[1, -1]
"""
alist = [a() for a in args]
print(alist)
if __name__ == '__main__':
import doctest; doctest.testmod()
Run Code Online (Sandbox Code Playgroud)
换一种说法:
>>> t = 1, -1
>>> args = []
>>> for i in t:
... args.append(lambda: i)
... …Run Code Online (Sandbox Code Playgroud) python closures list-comprehension generator-expression late-binding
我一直在理论上运行生成器表达式比普通循环更有效.但后来我遇到了以下示例:编写一个给出数字的函数N,以及一些因子ps,返回所有数字的总和,N这是至少一个因子的倍数.
这是循环版本和更短的生成器表达式版本:
def loops(N, ps):
total_sum = 0
for i in xrange(N):
for p in ps:
if i%p == 0:
total_sum += i
break
return total_sum
def genexp(N, ps):
return sum(i for i in xrange(N)
if any(i%p == 0 for p in ps))
Run Code Online (Sandbox Code Playgroud)
我希望两者的表现大致相同,理解版本可能会快一点,但我没想到的是:
for func in ('loops', 'genexp'):
print func, timeit.timeit('%s(100000, [3,5,7])' % func,
number=100,
setup='from __main__ import %s' % func)
loops 2.82878184319
genexp 10.1663100719
Run Code Online (Sandbox Code Playgroud)
慢4倍甚至不接近!为什么?我有什么误会?
python performance generator generator-expression python-2.7
假设您有这样的函数:
def give_me_many(*elements):
#do something...
Run Code Online (Sandbox Code Playgroud)
你这样称呼它:
generator_expr = (... for ... in ... )
give_me_many(*generator_expr)
Run Code Online (Sandbox Code Playgroud)
这些元素是否会被懒惰地调用,或者在执行函数之前,生成器是否会运行所有可能数百万个元素?
我有一个简单的清单.
>>> a = [0, 1, 2]
Run Code Online (Sandbox Code Playgroud)
我想使用列表推导从它创建一个新列表.
>>> b = [x*2 for x in a]
>>> b
[0, 2, 4]
Run Code Online (Sandbox Code Playgroud)
很简单,但是如果我只想操作非零元素呢?
'if'在列表推导中需要'else',所以我想出了这个.
>>> b = [x*2 if x != 0 else None for x in a]
>>> b
[None, 2, 4]
Run Code Online (Sandbox Code Playgroud)
但理想的结果是.
>>> b
[2, 4]
Run Code Online (Sandbox Code Playgroud)
我可以这样做
>>> a = [0, 1, 2]
>>> def f(arg):
... for x in arg:
... if x != 0:
... yield x*2
...
>>> list(f(a))
[2, 4]
Run Code Online (Sandbox Code Playgroud)
或使用'过滤器'和lambda
>>> a = [0, …Run Code Online (Sandbox Code Playgroud) 在Python中,有没有办法在没有"x in"变量的情况下编写这个列表理解(因为它完全没用)?同样适用于生成器表达式.我怀疑这种情况经常发生,但我偶然发现了几次,很想知道.
这是一个例子:
week_array = ['']*7
four_weeks = [week_array[:] for x in range(4)]
Run Code Online (Sandbox Code Playgroud)
(也许,是否有更优雅的方式来构建它?)
在Django中,是否有为QuerySet编写复杂的自定义过滤器的标准方法?
正如我可以写的那样
MyClass.objects.all().filter(field=val)
Run Code Online (Sandbox Code Playgroud)
我想做这样的事情:
MyClass.objects.all().filter(customFilter)
Run Code Online (Sandbox Code Playgroud)
我可以使用生成器表达式
(x for x in MyClass.objects.all() if customFilter(x))
Run Code Online (Sandbox Code Playgroud)
但这会失去可链接性以及QuerySets提供的任何其他功能.
考虑以下函数,其输出应该是一系列迭代的笛卡尔积:
def cart(*iterables):
out = ((e,) for e in iterables[0])
for iterable in iterables[1:]:
out = (e1 + (e2,) for e1 in out for e2 in iterable)
return out
Run Code Online (Sandbox Code Playgroud)
当生成器理解被列表推导替换时,工作正常.当只有2个迭代时也可以工作.但是,当我尝试
print(list(cart([1, 2, 3], 'ab', [4, 5])))
Run Code Online (Sandbox Code Playgroud)
我明白了
[(1, 4, 4), (1, 4, 5), (1, 5, 4), (1, 5, 5),
(2, 4, 4), (2, 4, 5), (2, 5, 4), (2, 5, 5),
(3, 4, 4), (3, 4, 5), (3, 5, 4), (3, 5, 5)]
Run Code Online (Sandbox Code Playgroud)
为什么这个而不是笛卡儿产品?
python ×10
closures ×1
dictionary ×1
django ×1
generator ×1
if-statement ×1
late-binding ×1
parentheses ×1
performance ×1
python-2.7 ×1
string ×1