Python 如果元组中的第二项是连续的,则从元组中提取索引

Python extract indices from tuples if second item in tuple is sequential

我有一个元组列表,它是从另一个列表中的某些项目生成的。如果第二个元组项是连续的,我想在列表中获取索引(元组中的第一项)。

例如名为“已处理”的列表

[(1, 'Chip 1'),
 (1, 'Chip 2'),
 (1, 'Chip 3'),
 (2, 'Chip 4'),
 (4, 'Chip 1'),
 (4, 'Chip 2'),
 (4, 'Chip 3'),
 (4, 'Chip 4'),
 (5, 'Chip 5'),
 (7, 'Chip 1'),
 (7, 'Chip 2'),
 (7, 'Chip 3'),
 (7, 'Chip 4'),
 (8, 'Chip 5'),
 (10, 'Chip 1'),
 (10, 'Chip 2'),
 (10, 'Chip 3'),
 (12, 'Chip 1'),
 (12, 'Chip 2'),
 (14, 'Chip 1'),
 (16, 'Chip 1'),
 (16, 'Chip 2'),
 (18, 'Chip 1'),
 (18, 'Chip 2'),
 (20, 'Chip 1'),
 (20, 'Chip 2'),
 (20, 'Chip 3'),
 (20, 'Chip 4'),
 (23, 'Chip 1'),
 (25, 'Chip 1'),
 (27, 'Chip 1'),
 (27, 'Chip 2')]

我可以使用 more_itertools 获取顺序列表中的筹码,但我不知道如何进一步处理。谁能帮我算一下?

import more_itertools as mit
chip_nums = [int(p[1][-1]) for p in processed]
for group in mit.consecutive_groups(chip_nums):
    print(list(group))

[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3]
[1, 2]
[1]
[1, 2]
[1, 2]
[1, 2, 3, 4]
[1]
[1]
[1, 2]

你可以这样做:

(您会在该代码后找到解释)

from itertools import groupby
from operator import itemgetter

# PART 1

# List that will contain lists of indexes of "chip_nums". 
# Each list of indexes will correspond to consecutive chips values
list_of_indexes =list()

for k,g in groupby(enumerate(chip_nums),lambda x:x[0]-x[1]):
    group = (map(itemgetter(0),g))
    group = list(map(int,group))
    list_of_indexes.append(group)


# PART 2

# From the retrieved indexes, get fist value in tuple ("index in tuple")
list_of_indexes_contained_in_tuples = list()

for indexes in list_of_indexes:
    consecutive_indexes = list()

    for index in indexes:
        tuple_in_processed = processed[index]
        index_in_tuple = tuple_in_processed[0]
        consecutive_indexes.append(index_in_tuple)
    list_of_indexes_contained_in_tuples.append(consecutive_indexes)


print(list_of_indexes_contained_in_tuples)

输出:

[[1, 1, 1, 2], [4, 4, 4, 4, 5], [7, 7, 7, 7, 8], [10, 10, 10], [12, 12], [14], [16, 16], [18, 18], [20, 20, 20, 20], [23], [25], [27, 27]]

解释:

“第 1 部分”是 more_itertools 中函数 consecutive_groups 的修改版本。 不知道大家知不知道,consecutive_groups的源码(https://github.com/more-itertools/more-itertools/blob/master/more_itertools/more.py) is an implementation of this recipe that one can find on Python.org here: https://docs.python.org/2.6/library/itertools.html#examples

这个食谱最初写于 Python 2.6:

from operator import itemgetter
from itertools import groupby
data = [2, 3, 4, 5, 12, 13, 14, 15, 16, 17]
for k, g in groupby(enumerate(data), lambda (i,x):i-x):
    print map(itemgetter(1), g)

在Python3中转置,你会得到这个:

from operator import itemgetter
from itertools import groupby
data = [2, 3, 4, 5, 12, 13, 14, 15, 16, 17]
for k, g in groupby(enumerate(data), lambda x:x[0]-x[1]):
    print(list(map(itemgetter(1), g)))

修改包括将 lambda 函数改编为 Python 3。 请注意,我们还用 list() 包装了 map 函数,以便获取列表对象而不是地图对象。

就目前而言,通过此功能,我们可以使用您提供的代码获得您所获得的功能。

输出:

[2, 3, 4, 5]
[12, 13, 14, 15, 16, 17]

现在,我们将修改此函数以获取元素的索引而不是列表中的值(此处命名为“数据”)。为此,我们只需将 0 作为参数传递给 itemgetter 而不是 1:

data = [2, 3, 4, 5, 12, 13, 14, 15, 16, 17]
for k, g in groupby(enumerate(data), lambda x:x[0]-x[1]):
    print(list(map(itemgetter(0), g)))

不,我们有索引。

输出:

[0, 1, 2, 3]
[4, 5, 6, 7, 8, 9]

第二部分只是使用索引来获取元组中的第一个项目(所以是你想要的索引)。

所以,简而言之,我改编了 more_itertools 中的原始函数 consecutive_groups,以便 return 项目的索引而不是它们的值,并使用这些索引来检索每个元组中的第一个值。

groups 包含 processed 列表中连续的元素(开始和结束 )的索引。
注意: 一些元组包含 same/equal 开始和结束值,表示没有连续性。

groups = []
start = 0
for i in range(len(processed) - 1):
    if int(processed[i][1].split()[-1]) + 1 == int(
        processed[i + 1][1].split()[-1]
    ):  # checks if the next element is 1 greater than previous element
        pass
    else:
        groups.append((start, i))  # stores the start and ending index of a continuous group
        start = i + 1
groups.append((start, i + 1))  # this handles the last remaining element

index_list = [[item[0] for item in processed[start : end + 1]] for start, end in groups]

输出:

[[1, 1, 1, 2], [4, 4, 4, 4, 5], [7, 7, 7, 7, 8], [10, 10, 10], [12, 12], [14], [16, 16], [18, 18], [20, 20, 20, 20], [23], [25], [27, 27]]

itertoolsoperator 个模块的游行:

from itertools import islice
from operator import itemgetter

import more_itertools as mit


it = iter(processed)
getter = itemgetter(0)
chip_nums = map(lambda x: int(x[1][-1]), processed)
for group in mit.consecutive_groups(chip_nums):
    print([*islice(map(getter, it), len([*group]))])

输出:

[1, 1, 1, 2]
[4, 4, 4, 4, 5]
[7, 7, 7, 7, 8]
[10, 10, 10]
[12, 12]
[14]
[16, 16]
[18, 18]
[20, 20, 20, 20]
[23]
[25]
[27, 27]