【问题标题】:python reference preceding items in list looppython在列表循环中引用前面的项目
【发布时间】:2016-10-19 21:33:53
【问题描述】:

我正在尝试遍历列表,但同时参考之前的项目,以便进行比较。

这是我的代码

list1=[(1,'a','hii'),(2,'a','byee'),(3,'a','yoo'),(4,'b','laa'),(5,'a','mehh')]

我想循环遍历我的 list1 元组,如果元组中的第二个值与之前元组中的第二个值相同(都 =='a'),则连接元组中的第三个项目。

我想要的输出

list2=[('a','hii,byee,yoo'),('b','laa'),('a','mehh')]

我的尝试

for item in list1:
    for item2 in list2:
            if item[0]==(item2[0]-1) and item[1]==item2[1]:
                     print item[2]+','+item2[2]
            elif item[0] != item2[0]-1:
                    continue
            elif item[0]==(item2[0]-1) and item[1] != item2[1]:
                     print item[2]

输出错误

hii,byee
byee,yoo
yoo
laa

从前 2 个输出来看,循环似乎只查看前面的值,而不是前面的 2 个或更多值。因此,它只将 2 个单词连接在一起,而不是应有的 3 个单词。输出也会有重复。

我该如何解决这个问题?

【问题讨论】:

  • 你真的只想合并相邻的元组吗?也就是说,前三个都被合并了,但最后一个,'mehh',不与列表前面的那些合并?
  • 它必须是相邻的,并且元组的第二个值必须相同(都=='a'或其他值)并且元组的第一项必须大于前一个乘 1。因此,如果满足要求,它可能是前 3 或前 'n'。此外,我的列表已经按元组的第一个值排序。

标签: python list loops


【解决方案1】:

我让这种方式变得比它需要的更难

def combine(inval):
    outval = [inval[0]]
    for item in inval[1:]:
        if item[0] == outval[-1][0] + 1 and item[1] == outval[-1][1]:
            outval[-1] = (item[0], item[1], ",".join([outval[-1][2], item[2]]))
            continue
        outval.append(item)
    return [(item[1], item[2]) for item in outval]

然后进行测试......

list1 = [(1,'a','hii'),(2,'a','byee'),(3,'a','yoo'),(4,'b','laa'),(5,'a','mehh')]
list2 = [(1,'a','hii'),(3,'a','byee'),(4,'a','yoo'),(5,'b','laa'),(6,'a','mehh')]
list3 = [(1,'a','hoo'),(3,'a','byee'),(5,'a','yoo'),(6,'a','laa'),(7,'a','mehh'),(9, 'b', 'nope')]

for l in (list1, list2, list3):
    print "IN:", l
    print "OUT:", combine(l)
    print

输出

IN: [(1, 'a', 'hii'), (2, 'a', 'byee'), (3, 'a', 'yoo'), (4, 'b', 'laa'), (5, 'a', 'mehh')]
OUT: [('a', 'hii,byee,yoo'), ('b', 'laa'), ('a', 'mehh')]

IN: [(1, 'a', 'hii'), (3, 'a', 'byee'), (4, 'a', 'yoo'), (5, 'b', 'laa'), (6, 'a', 'mehh')]
OUT: [('a', 'hii'), ('a', 'byee,yoo'), ('b', 'laa'), ('a', 'mehh')]

IN: [(1, 'a', 'hoo'), (3, 'a', 'byee'), (5, 'a', 'yoo'), (6, 'a', 'laa'), (7, 'a', 'mehh'), (9, 'b', 'nope')]
OUT: [('a', 'hoo'), ('a', 'byee'), ('a', 'yoo,laa,mehh'), ('b', 'nope')]

这既保证了第 0 索引处的连续数字,也保证了第 1 索引处的相等值。

【讨论】:

  • 我之前没有注意到关于 index-0 项目是顺序的任何要求。这将改变这一点。
【解决方案2】:

编辑:我已经根据要求更新了算法。您可以通过调用 group(values, sort=True) 对具有相同键的所有元组进行分组,或者通过调用 group(values) 仅对具有相同键的相邻元组进行分组。该算法还会收集最终元组的键之后的所有元素,而不是仅抓取第三个元素。

GroupBy 做得很好。您可以按元组中的第二个元素对值进行分组。然后对于每个组,抓取该组中的所有第三个元素并将它们连接成一个字符串:

import itertools

def keySelector(tup):
    return tup[1]

def group(values, sort=False):
    """
    Group tuples by their second element and return a list of 
    tuples (a, b) where a is the second element and b is the 
    aggregated string containing all of the remaining contents
    of the tuple.

    If sort=True, sort the tuples before grouping.  This will
    group all tuples with the same key.  Otherwise, only adjacent
    tuples wth the same key will be grouped.
    """

    if sort:
        values.sort(key=keySelector)

    grouped = itertools.groupby(values, key=keySelector)

    result = []
    for k, group in grouped:

        # For each element in the group, grab the remaining contents of the tuple
        allContents = [] 
        for tup in group:
            # Convert tuple to list, grab everything after the second item
            contents = list(tup)[2:]
            allContents.extend(contents)

        # Concatenate everything into one string
        aggregatedString = ','.join(allContents)

        # Add to results
        result.append((k, aggregatedString))

    return result

vals = [(1,'a','hii','abc','def'),
        (2,'a','byee'),
        (3,'a','yoo'),
        (4,'b','laa'),
        (5,'a','mehh','ghi','jkl')]

print(group(vals, sort=True))

输出:

[('a', 'hii,abc,def,byee,yoo,mehh,ghi,jkl'), ('b', 'laa')]

带有列表推导的简化版:

def getGroupContents(tuples):
    return ','.join(item for tup in tuples for item in list(tup)[2:])

def group(values, sort=False):
    if sort:
        values.sort(key=keySelector)

    grouped = itertools.groupby(values, key=keySelector)
    return [(k, getGroupContents(tuples)) for k, tuples in grouped]

【讨论】:

  • 您可以将keySelector 替换为itemgetter(1)
  • 怎么可以按第二个元素分组,但不能把最后一个(5,'a','mehh')?
  • 另外,我怎样才能将其他项目保留在元组中?就像我的元组有 (5,'a','mehh','xyz','abc') 并且我想把它全部放在输出中?
  • groupby 预计 values 已经是 sortedkey“通常,迭代需要已经在相同的键函数上排序。” i> 这样做:vals.sort(key=keySelector),或者如果您不想修改原始列表,请使用sortedsorted_values = sorted(vals)
  • 这个方案没有考虑元组的第0个索引是连续的要求。
猜你喜欢
  • 1970-01-01
  • 2017-09-07
  • 1970-01-01
  • 2022-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-08
  • 2020-03-31
相关资源
最近更新 更多