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

2024-04-26 12:16:13 发布

您现在位置:Python中文网/ 问答频道 /正文

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

例如,称为“已处理”的列表

[(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]

Tags: inimport列表formitmoregroup序列
3条回答

使用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]

你可以这样做:

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

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部分”是函数consecutive_groups的修改版本,来自more_itertools。 我不知道您是否知道,consecutive_groupshttps://github.com/more-itertools/more-itertools/blob/master/more_itertools/more.py)的源代码是这个配方的实现,可以在Python.org上找到: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)

在Python 3中转置后,您将看到:

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,以返回项的索引而不是它们的值,并使用这些索引检索每个元组中的第一个值

groups包含processed列表中连续的元素(开始和结束,包括)的索引。
注意:某些元组包含相同/相等的起始值和结束值,这表示没有连续性

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]]

相关问题 更多 >