如何根据特定元素(在本例中为第2个元素)从2d列表中删除连续重复项。
我尝试了几种与itertools的组合,但没有运气。
有谁能建议我如何解决这个问题?
INPUT
192.168.1.232 >>>>> 173.194.36.64 , 14 , 15 , 16
192.168.1.232 >>>>> 173.194.36.64 , 14 , 15 , 17
192.168.1.232 >>>>> 173.194.36.119 , 23 , 30 , 31
192.168.1.232 >>>>> 173.194.36.98 , 24 , 40 , 41
192.168.1.232 >>>>> 173.194.36.98 , 24 , 40 , 62
192.168.1.232 >>>>> 173.194.36.74 , 25 , 42 , 43
192.168.1.232 >>>>> 173.194.36.74 , 25 , 42 , 65
192.168.1.232 >>>>> 173.194.36.74 , 26 , 44 , 45
192.168.1.232 >>>>> 173.194.36.74 , 26 , 44 , 66
192.168.1.232 >>>>> 173.194.36.78 , 27 , 46 , 47
输出
192.168.1.232 >>>>> 173.194.36.64 , 14 , 15 , 16
192.168.1.232 >>>>> 173.194.36.119 , 23 , 30 , 31
192.168.1.232 >>>>> 173.194.36.98 , 24 , 40 , 41
192.168.1.232 >>>>> 173.194.36.74 , 25 , 42 , 43
192.168.1.232 >>>>> 173.194.36.78 , 27 , 46 , 47
这是预期的输出。
更新
以上给出的是列表的精美打印形式。
实际列表如下所示。
>>> for x in connection_frame:
print x
['192.168.1.232', '173.194.36.64', 14, 15, 16]
['192.168.1.232', '173.194.36.64', 14, 15, 17]
['192.168.1.232', '173.194.36.119', 23, 30, 31]
['192.168.1.232', '173.194.36.98', 24, 40, 41]
['192.168.1.232', '173.194.36.98', 24, 40, 62]
['192.168.1.232', '173.194.36.74', 25, 42, 43]
['192.168.1.232', '173.194.36.74', 25, 42, 65]
['192.168.1.232', '173.194.36.74', 26, 44, 45]
['192.168.1.232', '173.194.36.74', 26, 44, 66]
['192.168.1.232', '173.194.36.78', 27, 46, 47]
['192.168.1.232', '173.194.36.78', 27, 46, 67]
['192.168.1.232', '173.194.36.78', 28, 48, 49]
['192.168.1.232', '173.194.36.78', 28, 48, 68]
['192.168.1.232', '173.194.36.79', 29, 50, 51]
['192.168.1.232', '173.194.36.79', 29, 50, 69]
['192.168.1.232', '173.194.36.119', 32, 52, 53]
['192.168.1.232', '173.194.36.119', 32, 52, 74]
答案 0 :(得分:3)
因为你想要保留订单并且只是弹出连续的条目,我不知道你可以使用任何花哨的内置。所以,这里的蛮力"方法:
>>> remList = []
>>> for i in range(len(connection_frame)):
... if (i != len(connection_frame)-)1 and (connection_frame[i][1] == connection_frame[i+1][1]):
... remList.append(i)
...
for i in remList:
connection_frame.pop(i)
['192.168.1.232', '173.194.36.119', 32, 52, 53]
['192.168.1.232', '173.194.36.79', 29, 50, 51]
['192.168.1.232', '173.194.36.78', 28, 48, 49]
['192.168.1.232', '173.194.36.78', 27, 46, 67]
['192.168.1.232', '173.194.36.78', 27, 46, 47]
['192.168.1.232', '173.194.36.74', 26, 44, 45]
['192.168.1.232', '173.194.36.74', 25, 42, 65]
['192.168.1.232', '173.194.36.74', 25, 42, 43]
['192.168.1.232', '173.194.36.98', 24, 40, 41]
['192.168.1.232', '173.194.36.64', 14, 15, 16]
>>>
>>> for conn in connection_frame:
... print conn
...
['192.168.1.232', '173.194.36.64', 14, 15, 17]
['192.168.1.232', '173.194.36.119', 23, 30, 31]
['192.168.1.232', '173.194.36.98', 24, 40, 62]
['192.168.1.232', '173.194.36.74', 26, 44, 66]
['192.168.1.232', '173.194.36.78', 28, 48, 68]
['192.168.1.232', '173.194.36.79', 29, 50, 69]
['192.168.1.232', '173.194.36.119', 32, 52, 74]
>>>
或者,如果您想一次性完成所有操作,请使用列表理解:
>>> new_frame = [conn for conn in connection_frame if not connection_frame.index(conn) in [i for i in range(len(connection_frame)) if (i != len(connection_frame)-1) and (connection_frame[i][1] == connection_frame[i+1][1])]]
>>>
>>> for conn in new_frame:
... print conn
...
['192.168.1.232', '173.194.36.64', 14, 15, 17]
['192.168.1.232', '173.194.36.119', 23, 30, 31]
['192.168.1.232', '173.194.36.98', 24, 40, 62]
['192.168.1.232', '173.194.36.74', 26, 44, 66]
['192.168.1.232', '173.194.36.78', 28, 48, 68]
['192.168.1.232', '173.194.36.79', 29, 50, 69]
['192.168.1.232', '173.194.36.119', 32, 52, 74]
答案 1 :(得分:2)
import itertools
data = """192.168.1.232 >>>>> 173.194.36.64 , 14 , 15 , 16
192.168.1.232 >>>>> 173.194.36.64 , 14 , 15 , 17
192.168.1.232 >>>>> 173.194.36.119 , 23 , 30 , 31
192.168.1.232 >>>>> 173.194.36.98 , 24 , 40 , 41
192.168.1.232 >>>>> 173.194.36.98 , 24 , 40 , 62
192.168.1.232 >>>>> 173.194.36.74 , 25 , 42 , 43
192.168.1.232 >>>>> 173.194.36.74 , 25 , 42 , 65
192.168.1.232 >>>>> 173.194.36.74 , 26 , 44 , 45
192.168.1.232 >>>>> 173.194.36.74 , 26 , 44 , 66
192.168.1.232 >>>>> 173.194.36.78 , 27 , 46 , 47""".split("\n")
for k, g in itertools.groupby(data, lambda l:l.split()[2]):
print next(g)
打印出来
192.168.1.232 >>>>> 173.194.36.64 , 14 , 15 , 16
192.168.1.232 >>>>> 173.194.36.119 , 23 , 30 , 31
192.168.1.232 >>>>> 173.194.36.98 , 24 , 40 , 41
192.168.1.232 >>>>> 173.194.36.74 , 25 , 42 , 43
192.168.1.232 >>>>> 173.194.36.78 , 27 , 46 , 47
(这使用字符串列表,但很容易适应列表列表。)
答案 2 :(得分:0)
Pandas.groupby
是itertools.groupby
的替代方法,它还允许您跟踪原始列表的连续/非连续元素---通过给出行号而不是迭代器。像这样:
df = pandas.DataFrame(connection_frame)
print df
Out:
0 1 2 3 4
0 '192.168.1.232' '173.194.36.64' 14 15 16
1 '192.168.1.232' '173.194.36.64' 14 15 17
2 '192.168.1.232' '173.194.36.119' 23 30 31
3 '192.168.1.232' '173.194.36.98' 24 40 41
4 '192.168.1.232' '173.194.36.98' 24 40 62
5 '192.168.1.232' '173.194.36.74' 25 42 43
6 '192.168.1.232' '173.194.36.74' 25 42 65
7 '192.168.1.232' '173.194.36.74' 26 44 45
8 '192.168.1.232' '173.194.36.74' 26 44 66
9 '192.168.1.232' '173.194.36.78' 27 46 47
10 '192.168.1.232' '173.194.36.78' 27 46 67
11 '192.168.1.232' '173.194.36.78' 28 48 49
12 '192.168.1.232' '173.194.36.78' 28 48 68
13 '192.168.1.232' '173.194.36.79' 29 50 51
14 '192.168.1.232' '173.194.36.79' 29 50 69
15 '192.168.1.232' '173.194.36.119' 32 52 53
16 '192.168.1.232' '173.194.36.119' 32 52 74
然后,您可以按第二列对它们进行分组,然后将这些组打印为
gps = df.groupby(2).groups
print gps
Out:
{' 14': [0, 1],
' 23': [2],
' 24': [3, 4],
' 25': [5, 6],
' 26': [7, 8],
' 27': [9, 10],
' 28': [11, 12],
' 29': [13, 14],
' 32': [15, 16]}
查看各行号?在gps
的每个列表中有多种方法可以删除连续重复项。这是一个:
valid_rows = list()
for g in gps.values():
old_row = g[0]
valid_rows.append(old_row)
for row_id in range(1, len(g)):
new_row = g[row_id]
if new_row - old_row != 1:
valid_rows.append(new_row)
old_row = new_row
print valid_rows
Out: [5, 3, 9, 7, 0, 2, 15, 13, 11]
最后,将pandas DataFrame索引为valid_rows
。
print df.ix[sorted(valid_rows)]
Out:
0 '192.168.1.232' '173.194.36.64' 14 15 16
2 '192.168.1.232' '173.194.36.119' 23 30 31
3 '192.168.1.232' '173.194.36.98' 24 40 41
5 '192.168.1.232' '173.194.36.74' 25 42 43
7 '192.168.1.232' '173.194.36.74' 26 44 45
9 '192.168.1.232' '173.194.36.78' 27 46 47
11 '192.168.1.232' '173.194.36.78' 28 48 49
13 '192.168.1.232' '173.194.36.79' 29 50 51
15 '192.168.1.232' '173.194.36.119' 32 52 53