【问题标题】:Creating a python set/unique list创建一个 python 集合/唯一列表
【发布时间】:2020-01-01 07:50:53
【问题描述】:

我正在尝试使用 set 获取唯一列表,但我的循环方法显示了所有可能性并重复了一些已经存在的列表成员 - 它只是交换它们。我在想也许我应该使用字典 - 只需让一个成员保持不变并避免使用当前的循环方法。

试过了:

a=['hello','mam','dictionary','why','lives','elvis','hey','indicatory']
x = 1
while x < len(a):
    for i in a:
        if signature(a[x]) == signature(i) and a[x] != i:
            anagram=print([a[x],i],end =' ')
    x += 1

print(set(anagram))

出现错误:

IndexError: 列表索引超出范围

我遇到问题的代码:

def signature(word):
    return ''.join(sorted(word))

a=['hello','mam','dictionary','why','lives','elvis','hey','indicatory']

x = 1
unique_list = []
while x < 8:
    for i in a:
        if signature(a[x]) == signature(i) and a[x] != i:
            y = (a[x], i)
            unique_list.append(y)                                            
    x += 1

print(list(set(unique_list)))

实际结果: [('lives', 'elvis'), ('elvis', 'lives'), ('indicatory', 'dictionary'), ('dictionary', 'indicatory')]

预期结果: [('lives', 'elvis'), ('indicatory', '字典')]

【问题讨论】:

  • 你说得对,字典是自然的选择。您可以创建一个列表,其键是签名,其值是单词列表。
  • 列表 a 的元素从 0 到 len(a)-1 枚举。因此,当您的索引 x 达到 len(a) (8) 时,它会生成“列表索引超出范围”错误。

标签: python list set immutability anagram


【解决方案1】:

考虑使用defaultdict。然后你可以做

from collections import defaultdict
d = defaultdict(list)
a = ['hello','mam','dictionary','why','lives','elvis','hey','indicatory']
for i in a:
    d[''.join(sorted(i))].append(i)
out = [tuple(i) for i in d.values() if len(i) > 1]
print(out)

打印

[('dictionary', 'indicatory'), ('lives', 'elvis')]

【讨论】:

  • 这是最Pythonic的一个。我打算在我的答案中添加一个类似的版本。
【解决方案2】:

这应该可行:

a=['hello','mam','dictionary','why','lives','elvis','hey','indicatory']
anagrams = set([])
for i in range(len(a)):
    for j in range(i+1, len(a)):
        if sorted(a[i]) == sorted(a[j]):
            anagrams.add((a[i], a[j]))
print(anagrams)

【讨论】:

  • 或者你可以打印print(list(anagrams))这样的列表来得到你想要的结果
【解决方案3】:

首先,你似乎有两个循环试图做同样的事情?这很令人困惑。 其次,您可以对每个元组进行排序,然后创建一个集合,一直在字符串和元组之间进行转换,但更简单的解决方案是:

x = 0
unique_list = []
while x < len(a):
    for i in a[x + 1:]:
        if signature(a[x]) == signature(i):
            unique_list.append((a[x], i))
    x += 1
print(unique_list)

这里,a[x + 1:] 是一个切片,它只取列表中我们当前检查的单词之后的单词。通过构造,不会有重复,可以节省a[x] != i 检查的时间,并且可以减少迭代次数。

while 循环有点不合常规,因为我们只从列表中读取 a,更标准的方式是 for x in range(len(a)):,但可以按照您的喜好进行操作。

【讨论】:

    【解决方案4】:

    对于列表中的每个单词,只检查它后面的单词。这样你就不会有“反向重复”。
    下面是代码的修改(和改进)版本(也使用[Python 3.Docs]: Built-in Functions - enumerate(iterable, start=0),在迭代期间跟踪当前索引和当前元素)。

    code00.py

    #!/usr/bin/env python3
    
    import sys
    
    
    def signature(word):
        return sorted(word)
    
    
    def anagrams(word_list):
        result = list()
        for index0, word0 in enumerate(word_list):
            for _, word1 in enumerate(word_list[index0 + 1:]):  # Slice starting from the word that comes AFTER word0
                if signature(word0) == signature(word1):
                    result.append((word0, word1))
        return result
    
    
    def main():
        words = ["hello", "mam", "dictionary", "why", "lives", "elvis", "hey", "indicatory"]
        print(anagrams(words))
    
    
    if __name__ == "__main__":
        print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
        main()
        print("\nDone.")
    

    输出

    [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q057686401]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code00.py
    Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32
    
    [('dictionary', 'indicatory'), ('lives', 'elvis')]
    
    Done.
    

    【讨论】:

      【解决方案5】:

      您可以简单地使用以下代码来获取唯一列表。

          list = []
          for i in range(len(a)):
              if a[i] not in list:
                  list.append(a[i])
          print(list)        
      

      【讨论】:

        【解决方案6】:

        给你。我也解决了区分大小写问题。

        b=set()
        for x in a:
           i = 0
           i = i + 1
           for y in a[i:]:
              if len(x) == len(y):
                  if "".join(sorted(x.lower())) == "".join(sorted(y.lower())):
                      if x != y:
                          b.add(tuple((sorted((x,y)))))
         print b
        

        【讨论】:

        • 没有指导方针不将屏幕截图放在这里并且给出 -2 就像是一种气馁。无论如何我已经用代码更新了答案。
        • 请参阅this meta question 了解屏幕截图。在这种情况下,否决票的目的是鼓励您进行编辑,而不是阻止您回答。我删除了反对票,但您的代码有点奇怪。为什么这两行的唯一作用是设置i = 1?变量i 没有在循环中修改,并且没有真正意义。您确定要将初始化 i = 0 置于循环中吗?
        猜你喜欢
        • 1970-01-01
        • 2019-09-14
        • 1970-01-01
        • 1970-01-01
        • 2012-10-04
        • 2014-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多