使用Python 3迭代字符串

时间:2017-06-21 22:46:00

标签: python python-3.x

我想使用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)

4 个答案:

答案 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