【问题标题】:Longest string from a tuple in a list列表中元组中的最长字符串
【发布时间】:2022-01-24 11:30:52
【问题描述】:

我有两个字符串元组的列表: 例如,我使用这个元组列表,但当然列表通常更长:

[("Hello world","1"), ("Helloworld","2"),("Hi, Hello world","1"),("How are you","3"),("HiHelloworld","2")]

元组的两个字符串是消息和发送者ID,这些消息是可变长度的,唯一不变的是发送者ID。 我发现自己有一个列表,其中包含多个不同长度且具有相同发件人 ID 的消息,我只想获得一个包含每个发件人最长消息的列表: 例如在我的例子中是:

[("Hi, Hello world","1"),("How are you","3"),("HiHelloworld","2")]

我有点困惑,因为我不经常使用元组,所以我真的不知道如何进行。 我知道我应该在做任何事情之前对列表进行排序,没关系,我知道这样做,但是在那之后我如何为每个发送者设置最长的字符串,知道列表的每个元素不是字符串或整数而是元组?

非常感谢!

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    您可以在更新方法中使用推导式创建字典:

    L = [("Hello world","1"), ("Helloworld","2"),("Hi, Hello world","1"),
         ("How are you","3"),("HiHelloworld","2")]
    
    D = dict()
    D.update((s,m) for m,s in L if len(m)>=len(D.get(s,'')))
    
    {'1': 'Hi, Hello world', '2': 'HiHelloworld', '3': 'How are you'}
    

    您可以预先对列表进行排序,但这实际上比 update() 方法效率低:

    D = dict(map(reversed,sorted(L,key=lambda ms:len(ms[0]))))
    
    {'2': 'HiHelloworld', '1': 'Hi, Hello world', '3': 'How are you'}
    

    【讨论】:

    • 是保证还是实现细节?
    • @Bharel,我假设您指的是在提供给 D.update() 的生成器中使用 D.get()。我找不到明确的规范,但似乎不太可能更新迭代器不会在元素被消耗时进行更改(这也适用于 list.extend btw)。
    • 有很多事情可能会出错:锁定机制防止在修改内存时读取,在实际分配区域之前预先调整操作以获取长度(如str.join() 所做的) ,以及许多其他可能导致问题的边缘情况。除非规范允许,否则我倾向于认为这是一个实现细节(可能会保留下来,否则它会破坏这种代码,但仍然如此)。蜘蛛侠的感觉会因为那个麻烦而感到刺痛。
    【解决方案2】:

    您可以使用字典 (defaultdict) 来跟踪每个 ID 的最长消息:

    from collections import defaultdict
    
    # input
    l = [("Hello world","1"), ("Helloworld","2"),("Hi, Hello world","1"),("How are you","3"),("HiHelloworld","2")]
    
    d = defaultdict(lambda:('', float('-inf')))
    for msg, ID in l:
        if len(msg) > len(d[ID][0]):
            d[ID] = (msg, ID)
    out = list(d.values())
    

    输出:

    [('Hi, Hello world', '1'), ('HiHelloworld', '2'), ('How are you', '3')]
    

    【讨论】:

    • 可能值得一提的是,此解决方案不需要对列表进行排序,因为 OP 认为它需要做任何事情:`我知道我应该在做任何事情之前对列表进行排序`
    【解决方案3】:

    您可以在插入前比较当前大小时使用常规字典对其进行映射:

    messages = [("Hello world","1"), ("Helloworld","2"),("Hi, Hello world","1"),("How are you","3"),("HiHelloworld","2")]
    
    def get_longest_messages(messages):
        output = {}
        for message, sender in messages:
            if len(message) > len(output.get(sender, "")):
                output[sender] = message
        return output
    
    print(get_longest_messages(messages))
    

    输出:

    {'1': 'Hi, Hello world', '2': 'HiHelloworld', '3': 'How are you'}
    

    我强烈建议将输出保留为字典。

    【讨论】:

      【解决方案4】:

      对列表进行排序后,您可以创建一个包含来自同一发件人 ID 的所有字符串的辅助列表,然后应用 max 函数以从该辅助列表中获取最长的字符串。

      >>> mylist = ['123','123456','1234']
      >>> print max(mylist, key=len)
      123456
      

      不同的方法可以在this post看到。

      【讨论】:

        猜你喜欢
        • 2020-09-27
        • 1970-01-01
        • 2013-04-21
        • 2021-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-14
        相关资源
        最近更新 更多