如何从带有重复值的逗号分隔字符串创建具有唯一索引的Python列表?
我正在尝试用 Python 中的 split()
方法把一个用逗号分隔的字符串转换成一个列表。我发现这样做后,列表里有很多重复的索引,这似乎是因为有些值是相同的。我希望每个元素都有自己独特的顺序索引,这样我就可以通过索引来按位置访问它们,我该怎么做呢?以下是相关的代码:
haproxy_socket_data ='''
pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,
fe,FRONTEND,,,0,1,2000,45,0,8415,0,0,45,,,,,OPEN,,,,,,,,,1,1,0,,,,0,0,0,1,,,,0,0,0,45,0,0,,0,1,45,,,
bend,host1,0,0,0,0,,0,0,0,,0,,0,0,0,0,UP,1,1,0,0,0,113,0,,1,2,1,,0,,2,0,,0,L4OK,,0,0,0,0,0,0,0,0,,,,0,0,
'''
haproxy_socket_data = haproxy_socket_data.splitlines()
for line in haproxy_socket_data:
stats = line.split(',')
print line
print stats
for i in stats:
print i
print "index: %s" % stats.index(i)
这是这段代码的输出结果: https://gist.github.com/wjimenez5271/74df2b16b540a7d9de0c
我找到了这些关于如何将数据放入列表的例子,但没有一个解决我这个情况,也就是有些值是相同的:
4 个回答
看起来你有重复的索引,其实是因为在Python中,list.index()这个方法只会返回那个值第一次出现的位置。你可以试着用一个for循环,逐个索引这些值,而不是用那种自动迭代的for in循环。
如果你想保留索引,可以使用一个带有 enumerate
的 for
循环,或者用 range()
:
haproxy_socket_data = """
pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,
fe,FRONTEND,,,0,1,2000,45,0,8415,0,0,45,,,,,OPEN,,,,,,,,,1,1,0,,,,0,0,0,1,,,,0,0,0,45,0,0,,0,1,45,,,
bend,
"""
haproxy_socket_data = haproxy_socket_data.splitlines()
for line in haproxy_socket_data:
stats = [item for item in line.split(',') if len(item) >= 1] #Gets rid of items like ['']
print line
print stats
for ind, it in enumerate(stats):
print it
print "index: %d" % ind
或者,使用 range(len())
:
haproxy_socket_data ="""
pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,
fe,FRONTEND,,,0,1,2000,45,0,8415,0,0,45,,,,,OPEN,,,,,,,,,1,1,0,,,,0,0,0,1,,,,0,0,0,45,0,0,,0,1,45,,,
bend,
"""
haproxy_socket_data = haproxy_socket_data.splitlines()
for line in haproxy_socket_data:
stats = [item for item in line.split(',') if len(item) >= 1] #Gets rid of items like ['']
print line
print stats
for i in range(len(stats):
print stats[i]
print "index: %d" % i
list.index()
会返回这个项目的第一次出现的位置:
>>> item = [1, 2, 5, 7, 3, 3, 8, 9, 5]
>>> item.index(5)
2
>>> item[2]
5
>>> item[8]
5
>>>
使用 enumerate()
:
>>> for ind, it in enumerate(item):
... if it == 5:
... print ind
...
2
8
>>>
如果数据值中有逗号,那么直接用 split(",")
来分割就不对了。
可以看看 csv 模块。这个模块可以自动判断(也就是“嗅探”)正确的分割和引号参数。它还可以把每一行数据读到一个字典里,这样你就可以通过名字来引用数据,而不需要再数列数了!
举个例子。注意反斜杠,这样嗅探器才能从数据的第一行读取标题:
haproxy_socket_data ='''\
pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,
fe,FRONTEND,,,0,1,2000,45,0,8415,0,0,45,,,,,OPEN,,,,,,,,,1,1,0,,,,0,0,0,1,,,,0,0,0,45,0,0,,0,1,45,,,
bend,host1,0,0,0,0,,0,0,0,,0,,0,0,0,0,UP,1,1,0,0,0,113,0,,1,2,1,,0,,2,0,,0,L4OK,,0,0,0,0,0,0,0,0,,,,0,0,
'''
import csv, StringIO
dialect = csv.Sniffer().sniff(haproxy_socket_data)
reader = csv.reader(
StringIO.StringIO(haproxy_socket_data), dialect=dialect,
)
for row in reader:
print row
print
dictr = csv.DictReader(
StringIO.StringIO(haproxy_socket_data),
dialect=dialect,
)
for drow in dictr:
print 'svname',drow['svname']
输出结果:
['pxname', 'svname', 'qcur', 'qmax', 'scur', 'smax', 'slim', 'stot', 'bin', 'bout', 'dreq', 'dresp', 'ereq', 'econ', 'eresp', 'wretr', 'wredis', 'status', 'weight', 'act', 'bck', 'chkfail', 'chkdown', 'lastchg', 'downtime', 'qlimit', 'pid', 'iid', 'sid', 'throttle', 'lbtot', 'tracked', 'type', 'rate', 'rate_lim', 'rate_max', 'check_status', 'check_code', 'check_duration', 'hrsp_1xx', 'hrsp_2xx', 'hrsp_3xx', 'hrsp_4xx', 'hrsp_5xx', 'hrsp_other', 'hanafail', 'req_rate', 'req_rate_max', 'req_tot', 'cli_abrt', 'srv_abrt', ''] ['fe', 'FRONTEND', '', '', '0', '1', '2000', '45', '0', '8415', '0', '0', '45', '', '', '', '', 'OPEN', '', '', '', '', '', '', '', '', '1', '1', '0', '', '', '', '0', '0', '0', '1', '', '', '', '0', '0', '0', '45', '0', '0', '', '0', '1', '45', '', '', ''] ['bend', 'host1', '0', '0', '0', '0', '', '0', '0', '0', '', '0', '', '0', '0', '0', '0', 'UP', '1', '1', '0', '0', '0', '113', '0', '', '1', '2', '1', '', '0', '', '2', '0', '', '0', 'L4OK', '', '0', '0', '0', '0', '0', '0', '0', '0', '', '', '', '0', '0', '']
svname FRONTEND svname host1
你对 index()
的功能有些误解。Python 的文档上是这么说的:
s.index(x[, i[, j]])
在 s 中,x 第一次出现的位置(从索引 i 开始,到索引 j 之前)
所以,每次你在代码中调用 stats.index(i)
时,它会返回 i
在 stats
中第一次出现的位置。
如果你想在遍历列表时跟踪每个元素的索引,你应该使用 enumerate()
:
for index, item in enumerate(stats):
print item
print "index: %s" % index