将随机列表中的项目附加到新列表

Bam*_*mbi 7 python random shuffle list append

对于文本分类项目(年龄),我正在制作我的数据的子集.我用文件名制作了3个列表,按年龄排序.我想要对这些列表进行随机播放,然后将每个混洗列表中的5000个文件名附加到新列表中.结果应该是具有15000个文件(5000 10s,5000 20s,5000 30s)的数据子集.你可以看到我到目前为止所写的内容.但我知道random.shuffle返回none和无类型对象不可迭代.我怎么解决这个问题?

def seed():
   return 0.47231099848

teens = [list of files]
tweens = [list of files]
thirthies = [list of files]
data = []
for categorie in random.shuffle([teens, tweens, thirthies],seed):
    data.append(teens[:5000])
    data.append(tweens[:5000])
    data.append(thirthies[:5000])
Run Code Online (Sandbox Code Playgroud)

Luc*_*hko 9

第一个问题是你正在改组包含3项[青少年,补间,战俘](甚至每个项目都是一个列表)的列表,而不是改组每个子列表

其次,你可以用random.sample而不是random.shuffle

for categ in [teens, tweens, thirthies]:
    data.append(random.sample(categ,5000])
Run Code Online (Sandbox Code Playgroud)

或者作为@JonClements在评论中建议您可以使用列表理解

categories = [teens, tweens, thirthies]
data = [e for categ in categories for e in random.sample(categ, 5000)]
Run Code Online (Sandbox Code Playgroud)

  • 每次只需添加``random.seed(0.47231099848)``后你的``import random``按@PM 2Ring解释 (2认同)

PM *_*ing 7

你是正确的,random.shuffle返回None.那是因为它将其列表参数原位洗牌,并且它是一个Python约定,其函数采用可变arg并使其返回mutate None.但是,你误解了randomarg random.shuffle:它需要是一个随机数生成器,而不是像你seed这样的函数总是返回相同的数字.

顺便说一句,您可以使用其seed功能为随机模块提供的标准随机数生成器播种.random.seed接受任何可哈希的对象作为其参数,尽管习惯上传递一个数字或字符串.你也可以传递它None(这里相当于没有传递arg),并且它将使随系统随机源播种随机数(如果没有系统随机源,则系统时间用作种子) ).如果seed在导入随机模块后没有显式调用,则相当于调用seed()

提供种子的好处是每次运行具有相同种子的程序时,各种随机模块函数产生的随机数将完全相同.这在开发和调试代码时非常有用:当输出不断变化时,很难跟踪错误.:)


有两种主要方法可以做你想要的.您可以随机播放列表,然后从中分割前5000个文件名.或者您可以使用该random.sample函数获取5000个随机样本.这样你就不需要改变整个列表了.

import random

random.seed(0.47231099848)

# teens, tweens, thirties are lists of file names
file_lists = [teens, tweens, thirties]

# Shuffle
data = []
for flist in file_lists:
    random.shuffle(flist)
    data.append(flist[:5000])
Run Code Online (Sandbox Code Playgroud)

运用 sample

# Sample
data = []
for flist in file_lists:
    data.append(random.sample(flist, 5000))
Run Code Online (Sandbox Code Playgroud)

我没有对此代码执行速度测试,但我怀疑它sample会更快,因为它只需要随机选择项目而不是移动所有列表项目.shuffle是相当有效的,所以你可能不会注意到运行时间的差异,除非你的青少年,补间和三十年代文件列表都有超过5000个文件名.

这两个循环都构成data一个包含3个子列表的嵌套列表,每个子列表中有5000个文件名.但是,如果您希望它是15000个文件名的平面列表,则只需使用该list.extend方法而不是list.append.例如,

data = []
for flist in file_lists:
    data.extend(random.sample(flist, 5000))
Run Code Online (Sandbox Code Playgroud)

或者我们可以使用带有双for循环的列表理解来完成它:

data = [fname for flist in file_lists for fname in random.sample(flist, 5000)]
Run Code Online (Sandbox Code Playgroud)

如果需要过滤内容data以构建最终文件列表,最简单的方法是向列表推导添加if条件.

假设我们有一个函数可以测试文件名是否是我们要保留的文件名:

def keep_file(fname):
    # if we want to keep fname, return True, otherwise return False
Run Code Online (Sandbox Code Playgroud)

然后我们就可以做到

data = [fname for flist in file_lists for fname in random.sample(flist, 5000) if keep_file(fname)]
Run Code Online (Sandbox Code Playgroud)

并且data只包含通过keep_file测试的文件名.

另一种方法是使用生成器表达式而不是列表推导来创建文件名,然后将其传递给内置filter函数:

data_gen = filter(keep_file, (fname for flist in file_lists for fname in random.sample(flist, 5000)))
Run Code Online (Sandbox Code Playgroud)

data_gen本身就是一个迭代器.你可以像这样建立一个列表:

data_final = list(data_gen)
Run Code Online (Sandbox Code Playgroud)

或者,如果您实际上并不需要将所有名称作为集合,并且您可以逐个处理它们,则可以将它放在for循环中,如下所示:

for fname in data_gen:
    print(fname)
    # Do other stuff with fname
Run Code Online (Sandbox Code Playgroud)

这使用较少的RAM,但缺点是它"消耗"文件名,因此一旦for完成循环data_gen将为空.

假设您编写了一个从每个文件中提取所需数据的函数:

def age_and_text(fname):
    # Do stuff that extracts the age and desired text from the file
    return fname, age, text
Run Code Online (Sandbox Code Playgroud)

您可以创建这样的(filename, age, text)元组列表:

data_gen = (fname for flist in file_lists for fname in random.sample(flist, 5000) if keep_file(fname))

final_data = [age_and_text(fname) for fname in data_gen]
Run Code Online (Sandbox Code Playgroud)

请注意我的第一个片段中的切片:flist[:5000].这需要前5000个flist项目,索引为0到4999(含)的项目.您的版本有teens[:5001],这是一个错误的错误.切片的工作方式与范围相同.因此range(5000)产生从0到4999的5000个数字.它以这种方式工作,因为Python(像大多数现代编程语言一样)使用从零开始的索引.


Aza*_*kov 5

shuffle返回None,不可迭代

你应该做

data = []
for category in [teens, tweens, thirthies]:
    category_copy = category[:]
    random.shuffle(category_copy, seed)
    data.append(category_copy[:5000])
Run Code Online (Sandbox Code Playgroud)