Python 确保列表中两个项目之间最小距离的生成器

Python 确保列表中两个项目之间最小距离的生成器,python,generator,Python,Generator,我试图创建一个脚本,它获取文件的内容,将其存储到容器中,然后伪随机地从容器中获取一行 该文件包含一首歌词、一个标签和一个链接,由a/t分隔,但我试图使代码对任何更改都具有弹性—从行中添加或删除元素 问题是伪随机发生器,我无耻地复制了它,但我真的不明白。 问题是矩阵不是可散列类型,而在生成器中我使用set()对其进行散列。 如何修复矩阵生成器的代码?据推测,它应该随机选择一行,但避免再次选择同一行太近 代码如下: #!/usr/bin/env python # -*- coding: utf-8

我试图创建一个脚本,它获取文件的内容,将其存储到容器中,然后伪随机地从容器中获取一行

该文件包含一首歌词、一个标签和一个链接,由a/t分隔,但我试图使代码对任何更改都具有弹性—从行中添加或删除元素

问题是伪随机发生器,我无耻地复制了它,但我真的不明白。 问题是矩阵不是可散列类型,而在生成器中我使用set()对其进行散列。 如何修复矩阵生成器的代码?据推测,它应该随机选择一行,但避免再次选择同一行太近

代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import random, collections, time

# Pseudo-random generator
def choice_gen(choices, min_dist):
    last_choices = collections.deque(maxlen=min_dist)
    choices = set(choices)
    while 1:
        c = random.choice(list(choices - set(last_choices)))
        last_choices.append(c)
        yield c

# Organizes the contents of the file in matrix 
# <Song lyric> <hashtag> <link>
songs_table = []
with open("songs.txt") as f:
    for txtline in f:
        song_data= txtline.split('\t')
        songs_table.append(song_data)

# Prints a pseudo-random row of the matrix
for song_data in choice_gen(songs_table,2):
    print "{}".format(song_list)
    time.sleep(2)

# With dictionary, only 2 values per song though,
# the script runs without issues here
# <Lyric> <hashtag>
"""     
song_dict = {}
with open("songs.txt") as f:
    for txtline in f:
        (key, val) = txtline.split('\t')
        song_dict[key] = val

for line in choice_gen(song_dict.items(),2):
        print "{}".format(line)
        time.sleep(2)
"""
#/usr/bin/env python
#-*-编码:utf-8-*-
导入随机、集合、时间
#伪随机发生器
def choice_gen(选项,最小距离):
最后的选项=collections.deque(maxlen=min\u dist)
选项=设置(选项)
而1:
c=random.choice(列表(选项-集合(最后的选项)))
最后的选择。附加(c)
产量c
#在矩阵中组织文件的内容
#   
歌曲_表=[]
打开(“songs.txt”)作为f:
对于f中的txtline:
song_data=txtline.split('\t')
歌曲表。追加(歌曲数据)
#打印矩阵的伪随机行
对于choice_gen(歌曲表,2)中的歌曲数据:
打印“{}”。格式(歌曲列表)
时间。睡眠(2)
#使用dictionary,每首歌只有2个值,
#脚本在这里运行没有问题
#  
"""     
宋_dict={}
打开(“songs.txt”)作为f:
对于f中的txtline:
(key,val)=txtline.split('\t')
宋词[key]=val
对于选项_gen(song_dict.items(),2)中的行:
打印“{}”。格式(行)
时间。睡眠(2)
"""

列表对象是可变的,因此不可散列。使用元组,元组是不可变的,因此是可散列的:

songs_table = []
with open("songs.txt") as f:
    for txtline in f:
        song_data= tuple(txtline.split('\t'))
        songs_table.append(song_data)
快速演示:

>>> some_nested_list = [['foo', 'bar', 'baz'], ['spam', 'ham', 'eggs']]
>>> set(some_nested_list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> set(tuple(el) for el in some_nested_list)
set([('foo', 'bar', 'baz'), ('spam', 'ham', 'eggs')])
>>一些嵌套列表=[['foo','bar','baz',['spam','ham','egs']]
>>>集合(一些嵌套列表)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:不可损坏的类型:“列表”
>>>集合(某些嵌套列表中el的元组(el)
套装([('foo','bar','baz'),('spam','ham','egs'))

那么您得到的回溯是什么?