我得到一些这样的数据
A=['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
我希望得到这样的结果,这意味着名称,最小数量,最大数量。我有100万这样的数据。
'A,1,5','B,2,5','C,2,200'
我试过这样的方式:
A=['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
B=[]
C=[]
for r in A:
B.append(r.split(',')[0])
B_set=list(set(B))
catagory_number=range(0,len(B_set),1)
for j in catagory_number:
numbers = []
for r in A:
if B_set[j]==r.split(',')[0]:
numbers.append(r.split(',')[1])
print numbers
正如您所看到的,它不起作用,我得到了将数据放在一起的问题。
['1']
['1', '2']
['1', '2', '4']
['1', '2', '4', '5']
['2']
['2', '20']
['2', '20', '200']
['2', '20', '200', '2']
['2']
['2', '3']
['2', '3', '4']
['2', '3', '4', '5']
有什么建议吗?
答案 0 :(得分:1)
您可以迭代list
并使用OrderedDict
导出最小值和最大值。最后你可以像我展示的那样重新创建字符串,但实际上你可能最好保留字典数据结构(取决于你接下来要做什么):
import collections
def sol(lst):
d = collections.OrderedDict()
for item in lst:
key, value = item.split(',')
value = int(value)
if key in d:
if value < d[key][0]:
d[key][0] = value
elif value > d[key][0]:
d[key][1] = value
else:
d[key] = [value, value] # key = letter; value = [min, max]
return ['{},{},{}'.format(key,*values) for key,values in d.items()] # in Python 2 use key,value[0],value[1]
示例:
my_lst = ['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
print(sol(my_lst))
# ['A,1,5', 'B,2,5', 'C,2,200']
答案 1 :(得分:0)
以列表作为默认值的defaultdict
可以为您提供很多帮助:
>>> from collections import defaultdict
>>> data = defaultdict(list)
>>> data['A']
[]
>>> data['A'].append(1)
>>> data['A'].append(2)
>>> data['B'].append(3)
>>> data
defaultdict(<type 'list'>, {'A': [1, 2], 'B': [3]})
这可能是您想用set
和多个循环编写的内容。 defaultdict
是一个标准结构,应该足够快,即使有很多值。
这是使用此数据结构的解决方案的开始:
from collections import defaultdict
data = defaultdict(list)
A = ['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
for couple in A:
letter, number = couple.split(',')
data[letter].append(int(number))
print(data)
# defaultdict(<type 'list'>, {'A': [1, 2, 4, 5], 'C': [2, 20, 200, 2], 'B': [2, 3, 4, 5]})
对于A
中的每个字母,您现在都有一个相应值的列表。提取min
和max
并编写所需列表并不难。
答案 2 :(得分:0)
你可以试试这个:
letter=[]
number=[]
A=['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
for couple in A:
a, b = couple.split(',')
if a not in letter:
letter.append(a)
number.append([b])
else:
ind=letter.index(a)
number[ind].append(b)
B=[]
i=0
while i<len(letter):
B.append(letter[i]+","+str(min(number[i]))+","+str(max(number[i])))
i+=1
print (B)
[&#39; A,1,5&#39;,&#39; B,2,5&#39;,&#39; C,2,200&#39;]
答案 3 :(得分:0)
您可以使用groupby
模块中的itertools
并使用此示例中的list comprehension
来实现您的目标:
from itertools import groupby
A = ['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
sub_final = (sorted(list(v), key = lambda x: int(x.split(",")[1])) for _,v in groupby(sorted(A), lambda x: x[0]))
final = ["{0},{1}".format(k[0],k[-1].split(',')[-1]) for k in sub_final]
print(final)
输出:
['A,1,5', 'B,2,5', 'C,2,200']
答案 4 :(得分:0)
可能不是最快但我认为这很容易阅读。因为我使用的是Python 3.4,所以无法提供格式化。
paste(sapply(maxchar - nchar(dat$v2), function(n)
paste(rep(" ", max(n,0)), collapse = "")), dat$v2, sep = "")
#[1] " 10" " 10" " 100" " 100" "1000" "1000"
答案 5 :(得分:0)
基本思想是在列表的基础上拆分列表,即A,B,C ......并找到每个列表的最小值和最大值。以下是一种方法:
#!/usr/bin/python
A=['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
headerList = []
assoNumList = []
finalList = []
# Iterate over the list to obtain the headers i.e. A,A,A,A,A,B,B,B....C,...
for a in range(len(A)):
header = A[a][0]
headerList.append(header)
# Convert the list into a set to get distinct headers i.e. A,B,C..
headerSet = set(headerList)
uniqueHeaderList = list(headerSet)
# Iterate over the unique header list to get all numbers associated
# with each header. Apply min and max functions over the number set
# to get the Header wise Min and Max numbers.
for i in range(len(uniqueHeaderList)):
for a in range(len(A)):
if(A[a][0] == uniqueHeaderList[i]):
assoNum = A[a][2:]
assoNumList.append(assoNum)
header = A[a][0]
result = header+","+min(assoNumList)+","+max(assoNumList)
finalList.append(result)
del assoNumList[:]
print(sorted(finalList))
#Output: ['A,1,5','B,2,5','C,2,200']