如何理解这个python代码?

时间:2013-01-31 02:44:22

标签: python

此代码来自Learning python一书,它用于对用逗号分隔的文本文件中的列求和。我真的无法理解第7,8和9行。 谢谢您的帮助。这是代码:

filename='data.txt'
sums={}
for line in open(filename):
    cols=line.split(',')
    nums=[int(col) for col in cols]
    for(ix, num) in enumerate(nums):
        sums[ix]=sums.get(ix, 0)+num
for key in sorted(sums):
    print(key, '=', sums[key])

2 个答案:

答案 0 :(得分:2)

看起来输入文件包含逗号分隔的整数行。该程序打印出每列的总和。

你已经混淆了缩进,这改变了程序的含义,而且开头写的并不是很好。这里有很多评论:

filename='data.txt'    # name of the text file

sums = {}              # dictionary of { column: sum }
                       #   not initialized, because you don't know how many columns there are

# for each line in the input file,
for line in open(filename):
    # split the line by commas, resulting in a list of strings
    cols = line.split(',')
    # convert each string to an integer, resulting in a list of integers
    nums = [int(col) for col in cols]

    # Enumerating a list numbers the items - ie,
    #   enumerate([7,8,9]) -> [(0,7), (1,8), (2,9)]
    # It's used here to figure out which column each value gets added to
    for ix, num in enumerate(nums):
        # sums.get(index, defaultvalue) is the same as sums[index] IF sums already has a value for index
        # if not, sums[index] throws an error but .get returns defaultvalue
        # So this gets a running sum for the column if it exists, else 0;
        # then we add the new value and store it back to sums.
        sums[ix] = sums.get(ix, 0) + num

# Go through the sums in ascending order by column -
#   this is necessary because dictionaries have no inherent ordering
for key in sorted(sums):                    
    # and for each, print the column# and sum
    print(key, '=', sums[key])

我会用不同的方式写出来;

之类的东西
from collections import Counter
sums = Counter()

with open('data.txt') as inf:
    for line in inf:
        values = [int(v) for v in line.split(',')]
        sums.update(enumerate(values))

for col,sum in sorted(sums.iteritems()):
    print("{}: {}".format(col, sum))

答案 1 :(得分:1)

假设你理解第1-6行......

第7行:

sums[ix]=sums.get(ix, 0)+num

sums.get(ix, 0)sums[ix]相同,但如果ix not in sums则返回0。因此,这与sums[ix] += num类似,只是如果这是您第一次看到0,它会首先将值设置为ix

因此,应该清楚的是,在此循环结束时,sums[ix]将具有列ix中所有值的总和。

这是一种愚蠢的方式来做到这一点。正如mgilson指出的那样,你可以使用defaultdict,这样你就不需要额外的逻辑了。或者,更简单地说,您可以使用list代替dict,因为这(通过连续的小数字索引)正是list的用途......

第8行:

for key in sorted(sums):

首先,您可以迭代任何dict,就像它是list或其他可迭代的一样,它与迭代sums.keys()具有相同的效果。因此,如果sums看起来像{ 0: 4, 1: 6, 2: 3 },那么您将迭代0, 1, 2

除了dict没有任何固有的顺序。您可能会获得0, 1, 2,或者您可能会获得1, 0, 2或任何其他订单。

因此,sorted(sums)只会按排序顺序返回list个键的副本,保证您按顺序获得0, 1, 2

同样,这很愚蠢,因为如果你刚开始使用list,你就会把事情做好。

第9行:

print(key, '=', sums[key])

这个应该是显而易见的。如果key迭代0, 1, 2,则会打印0 = 41 = 62 = 3

因此,换句话说,它打印出每个列号,以及该列中所有值的总和。