我想使用map,reduce,filter以更加pythonic的方式编写此代码。有人可以帮我这个。
这是一段简单的代码,它根据字符串在字符串中的位置为字符串赋值。
例如,对于字符串abaacab
a b a a c a b
1 2 3 4 occurrence of a
1 2 occurrence of b
1 occurrence of c
1+1+2+3+1+4+2 = 14
import sys
check, total = {}, 0
for i, v in enumerate(sys.argv[1]):
if v in check:
check[v] += 1
else:
check[v] = 1
total += check[v]
print(total)
答案 0 :(得分:4)
如果您想以当前的方式计算结果,我认为您当前的代码与Pythonic一样(唯一的例外是不必要的enumerate
调用)。
但是,我认为找到你的total
有一个更好的方法,而不是在计算时加上计数。每个值贡献的总数部分可以直接从该值的最终计数中计算出来(它是一个三角形数字)。这意味着您可以一次性计算值,并计算出最后的总数。
我是这样做的:
import sys
import collections
counts = collections.Counter(sys.argv[1])
total = sum(n * (n+1) // 2 for n in counts.values())
print(total)
答案 1 :(得分:1)
import sys
val = {v : sys.argv[1].count(v) for v in set(sys.argv[1])}
total = sum(val[k] * (val[k] + 1) // 2 for k in val)
3行... 1个导入和2行香草蟒蛇。
第一行创建了字符到计数的映射。然后,第二行找到列表理解中每个字符的序列总和,第二行sum
总计每个字符的总和。
输出:
val: {'a': 4, 'c': 1, 'b': 2}
total: 14
警告:这不高效,因为它计算每个字符的计数(线性复杂度)。
答案 2 :(得分:1)
如此愿意,这是另一个答案实际上根据您的需要做你想做的事。符合Python3,尚未在Python2上进行测试。
from functools import reduce, partial
total = reduce(lambda x, y: x + y, map(lambda x: x * (x + 1) // 2, map(partial(str.count, sys.argv[1]), set(sys.argv[1]))))
print(total)
输出
14
打破它:
partial(str.count, sys.argv[1]) ---- (1)
定义了map
适用于sys.argv
的高阶函数。这样,您的计数就会被创建。最终答案不需要dict,因此不会创建。
map(---(1)---, set(sys.argv[1])) ---- (2)
应用部分函数(1)
map(lambda x: x * (x + 1) // 2, ----(2)----) ----(3)
获取(2)生成的计数,然后应用AP获得总和。
reduce(lambda x, y: x + y, ----(3)----)
将(3)的总和加起来。
答案 3 :(得分:0)
我认为你的代码可以更加Pythonic的唯一方法是使用Counter
对象而不是常规dict
,这简化了dict
执行的实际计数:
>>> from collections import Counter
>>> counts = Counter()
>>> s = "abaacab"
>>> total = 0
>>> for c in s:
... counts[c] += 1
... total += counts[c]
...
>>> total
14