首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python逐行迭代csv,同时跟踪下一行的内容。

Python逐行迭代csv,同时跟踪下一行的内容。
EN

Stack Overflow用户
提问于 2014-12-04 21:36:06
回答 2查看 99关注 0票数 0

我有一个csv,结构如下:

代码语言:javascript
复制
user_id,user_name,code
0001,user_a,e-5
0001,user_a,s-N
0002,user_b,e-N
0002,user_b,t-5

我想对文件进行迭代,这样,在处理完用户之后,在进入下一个用户之前,根据已处理用户的code进行一些额外的工作。用户可以有多个条目,条目数可以从1到n。

例如,在处理用户时,我们跟踪用户标识/提到的代码的第一个字母。我已经把它加到清单上了。我们需要确保在处理特定用户(这是用户级别)之后,这个列表会被重置。

例如,让我们考虑user_id 0001,在我到达0002行之后,我希望添加更多与用户0001相关的行,其中这些新行具有我们以前没有看到的代码:

下面是我如何努力做到这一点的:

代码语言:javascript
复制
    with open(os.path.expanduser('out_put_csv_file.csv'), 'w+') as data_file:
        writer = csv.writer(data_file)
        writer.writerow(('user_id', 'user_name', 'code'))
        l_file = csv.DictReader(open('some_file_name'))
        previous_user = None
        current_user = None
        tracker = []
        for row in l_file:
            current_user = row['user_id']
            tracker.append(row['code'].split('-')[0])
            writer.writerow([row['user_id'], row['user_name'], row['code']])
            if current_user != previous_user:
                for l_code in list_with_all_codes:
                        if l_code not in tracker:
                               writer.writerow([row['user_id'], row['user_name'], l_code])
                tracker = []
            previous_user = current_user

问题是:我会注意到:

代码语言:javascript
复制
user_id,user_name,code
0001,user_a,e-5
0001,user_a,n
0001,user_a,t
0001,user_a,i
0001,user_a,s #don't want this
0001,user_a,s-N
0002,user_b,e-N
0002,user_b,n
0002,user_b,t # don't want this
0002,user_b,i
0002,user_b,ta-5

而不是那样,我要的是

代码语言:javascript
复制
    user_id,user_name,code
    0001,user_a,e-5
    0001,user_a,n
    0001,user_a,t
    0001,user_a,i
    0001,user_a,s-N
    0002,user_b,e-N
    0002,user_b,n
    0002,user_b,i
    0002,user_b,ta-5

我在这里做错什么了?做这件事最好的方法是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-04 22:04:01

您的问题是,您为新用户编写了一行数据,然后才意识到需要为旧用户填写数据.然后使用新用户名编写旧用户数据。

因为您想要编写关于前一个用户的多个数据位,所以需要保留他/她的整个行。当你看到一个新用户时,在你做任何其他事情之前,为老用户写数据(使用他的信息)。当没有任何以前的用户需要处理时,对于第一个用户有一个特例。

代码语言:javascript
复制
import os
import csv

open('some_file_name', 'w').write("""user_id,user_name,code
0001,user_a,e-5
0001,user_a,s-N
0002,user_b,e-N
0002,user_b,t-5
""")

list_with_all_codes = ['e', 's', 'n', 't', 'a']

def set_unused_codes(writer, row, tracker):
    for l_code in list_with_all_codes:
        if l_code not in tracker:
            writer.writerow([row['user_id'], row['user_name'], l_code])

with open(os.path.expanduser('out_put_csv_file.csv'), 'w+') as data_file:
    writer = csv.writer(data_file)
    writer.writerow(('user_id', 'user_name', 'code'))
    l_file = csv.DictReader(open('some_file_name'))
    previous_row = None
    tracker = []
    for row in l_file:
        if not previous_row:
            previous_row = row
        if row['user_id'] != previous_row.get('user_id'):
            set_unused_codes(writer, previous_row, tracker)
            previous_row = row
            tracker = []
        tracker.append(row['code'].split('-')[0])
        writer.writerow([row['user_id'], row['user_name'], row['code']])
    set_unused_codes(writer, row, tracker)

print(open('out_put_csv_file.csv').read())

输出是..。

代码语言:javascript
复制
user_id,user_name,code
0001,user_a,e-5
0001,user_a,s-N
0001,user_a,n
0001,user_a,t
0001,user_a,a
0002,user_b,e-N
0002,user_b,t-5
0002,user_b,s
0002,user_b,n
0002,user_b,a

如果您不介意您丢失的代码是按照什么顺序编写的,您可以使用集合来以微不足道的微不足道的数量来加快速度(我是否过度推广了这一点?!)

代码语言:javascript
复制
set_of_all_codes = set(list_of_all_codes)
... the for loop ...

    for code in set_of_all_codes - set(tracker):
        writer.writewrow(...)
票数 1
EN

Stack Overflow用户

发布于 2014-12-04 22:38:05

在了解当前数据单元完成之前,需要查看下一个数据单元的常见模式如下(用例后粗略描述)

代码语言:javascript
复制
oldname = ""
data = []

for row in input:
    n,name,code = row.split(',')
    if name != oldname:
        if data: flush(data)
        data = []
        oldname = name
    update(data,n,name,code)
# remember to flush the data buffer when you're done with your file
flush(data)

data可以是列表列表,如

代码语言:javascript
复制
def update(data, n, name, code):
    if not data:
       data.append(n)
       data.append(name)
       data.append([code])
    else:
       data[2].append(code)

关于flush,如果您不知道如何排序输出(这是您在Q后面的注释),I也不知道。但是这只是在data[2]list_of_all_codes上迭代的问题,您已经在原始代码中做了一些类似的事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27304569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档