我有一个csv,结构如下:
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相关的行,其中这些新行具有我们以前没有看到的代码:
下面是我如何努力做到这一点的:
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问题是:我会注意到:
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而不是那样,我要的是
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我在这里做错什么了?做这件事最好的方法是什么?
发布于 2014-12-04 22:04:01
您的问题是,您为新用户编写了一行数据,然后才意识到需要为旧用户填写数据.然后使用新用户名编写旧用户数据。
因为您想要编写关于前一个用户的多个数据位,所以需要保留他/她的整个行。当你看到一个新用户时,在你做任何其他事情之前,为老用户写数据(使用他的信息)。当没有任何以前的用户需要处理时,对于第一个用户有一个特例。
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())输出是..。
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如果您不介意您丢失的代码是按照什么顺序编写的,您可以使用集合来以微不足道的微不足道的数量来加快速度(我是否过度推广了这一点?!)
set_of_all_codes = set(list_of_all_codes)
... the for loop ...
for code in set_of_all_codes - set(tracker):
writer.writewrow(...)发布于 2014-12-04 22:38:05
在了解当前数据单元完成之前,需要查看下一个数据单元的常见模式如下(用例后粗略描述)
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可以是列表列表,如
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上迭代的问题,您已经在原始代码中做了一些类似的事情。
https://stackoverflow.com/questions/27304569
复制相似问题