[英]Is there a better pythonic way to write this code?
I am trying to read first and third columns from a text file and add them together. 我正在尝试从文本文件中读取第一列和第三列,并将它们添加在一起。
Following code works perfectly and gives me the result I need but trying to find out if there is a better more pythonic way to write this? 下面的代码可以完美地工作,并为我提供所需的结果,但是尝试找出是否有更好的pythonic方式编写此代码?
with open('random.txt', 'r') as fn:
next(fn)
numbers = fn.readlines()
first_col = [int(x.split(',')[0]) for x in numbers]
third_col = [int(y.split(',')[2]) for y in numbers]
result = [v + z for v, z in zip(first_col, third_col)]
print(result)
The random file is literally a random file. 随机文件实际上是一个随机文件。
col1,col2,col3
44,65,78
55,87,98
12,32,62
Result: 结果:
[122, 153, 74]
You can use zip
: 您可以使用
zip
:
with open('random.txt', 'r') as fn:
next(fn)
first_col, _, third_col = [
*zip(*(int(x) for x in map(lambda x: x.split(','), fn))
]
...
results = [x+y for x, y in zip(first_col, second_col)]
Or if you do not need to hold the cols: 或者,如果您不需要按住cols:
results = [
x+y for x, _, y in zip(*(int(x) for x in map(lambda x: x.split(','), fn))
]
In addition to the answers provided here, you can use csv
package to process the file. 除了此处提供的答案外,您还可以使用
csv
包来处理文件。
import csv
with open('random.txt', 'r') as fn:
csv_reader = csv.reader(fn)
next(csv_reader, None) # skip the headers
result = [int(f)+int(t) for f,_, t in csv_reader]
print result
The easiest solution will be to use pandas
if you are comfortable with it. 如果您愿意的话,最简单的解决方案是使用
pandas
。
import pandas as pd
df = pd.read_csv('random.txt')
print df.col1 + df.col2
If you want the result as a list
, 如果您希望将结果作为
list
,
import pandas as pd
df = pd.read_csv('random.txt')
res = df.col1 + df.col2
print res.tolist()
I would say the easiest way is to just sticking to the basics, there is no correct pythonic
way! 我会说最简单的方法就是坚持基础知识,没有正确的
pythonic
方法! You can make your code as easy and as complex you want. 您可以使代码既简单又复杂。
import csv
res = []
with open('file.txt', 'r') as fp:
#Open csv file
reader = csv.reader(fp)
next(reader)
#Iterate through rows and append the sum of first and third rows to a list
for row in reader:
res.append(int(row[0]) + int(row[2]))
print(res)
#[122, 153, 74]
import sys
import csv
with open(sys.argv[1]) as fh:
reader = csv.reader(fh)
rows = [list(map(int, row)) for row in reader]
sums = [v + z for v, _, z in rows]
print(sums) # [122, 153, 74]
Your code is "pythonic" enough, but you're doing more work and using more space than you need to. 您的代码足够“ pythonic”,但是您需要做更多的工作,使用的空间也更多。
with open('random.txt', 'r') as fn:
next(fn) # skip the first row
total = 0
for row in fn:
first_col, _, third_col = row.split(',')
total += int(first_col) + int(third_col)
print(result)
You could tidy this up with a function perhaps 你可以用一个函数整理一下
def sum_row(row):
first_col, _, third_col = row.split(',')
return int(first_col) + int(third_col)
with open('random.txt', 'r') as fn:
next(fn) # skip the first row
result = sum(sum_row(row) for row in fn)
print result
If you need an industrial strength solution, ie, other people are using this too and you might need to maintain it in the future, use csv. 如果您需要工业强度解决方案,即其他人也在使用它,并且将来可能需要维护它,请使用csv。
import csv
def sum_row(row):
return int(row[0]) + int(row[2])
with open('random.txt', 'r') as fn:
reader = csv.reader(fn)
result = sum(sum_row(row) for row in fn)
There is another option with one-liner list comprehension, but we must use the methodcaller
higher order function, to split each line from the file. 还有一个具有单行列表理解的选项,但是我们必须使用
methodcaller
高阶函数来从文件中拆分每一行。
The list comprehension gets lines from the file and then the map
function executes a split(",")
method on each one to transform it to a list of columns. 列表推导从文件中获取行,然后
map
函数在每个函数上执行split(",")
方法以将其转换为列列表。
from operator import methodcaller
with open('random.txt','r') as f:
next(f)
sum = [ int(c1)+int(c3) for c1,_,c3 in map(methodcaller("split", ","),f)]
sum
The additional advantage is that we can convert it into a generator without wasting any memory. 另一个好处是我们可以将其转换为生成器而不会浪费任何内存。
from operator import methodcaller
with open('data','r') as f:
next(f)
v = ( int(c1)+int(c3) for c1,_,c3 in map(methodcaller("split", ","),f))
print(list(v)) # just to print the result
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.