简体   繁体   English

有没有更好的pythonic方式来编写此代码?

[英]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]

If you can use numpy then my suggestion is to use loadtxt function: 如果可以使用numpy那么我的建议是使用loadtxt函数:

import numpy as np
np.loadtxt('random.txt', dtype=int, skiprows=1, delimiter=',', usecols=(0, 2)).sum(axis=1).tolist()

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM