【问题标题】:Python 3.8 random.choice not working as expected when making choice from list generated from file从文件生成的列表中进行选择时,Python 3.8 random.choice 无法按预期工作
【发布时间】:2023-01-03 23:24:02
【问题描述】:

我正在使用 python 3.8。我有 4 个包含文本部分的纯文本文件。我想使用 * 作为分隔符将每个文件分成这些部分的列表,并通过从每个列表中选择一个随机字符串并按给定顺序将它们连接在一起来生成单个文本字符串。它可以工作,除了它有时会从一个或多个文件中生成一个空白字符串。输出应包含每个文件的一段文本,按照代码和文本文件中的 sectionFiles 列表的顺序。

import os
import random
categories = []
result = ''
sourcePath = "C:\\posthelper\\categories\\positive"
os.chdir(sourcePath)

def generate(result):
  sectionFiles = ['intro.txt', 'body.txt', 'referral.txt', 'closing.txt']

  for item in sectionFiles:
    with open(item) as file:
      sectionString = file.read()
      sectionString = sectionString.replace("\n", "")
      sectionStringList = sectionString.split("*") 
      stringChoice = random.choice(sectionStringList)
      result += stringChoice
  return(result)

print(generate(result))

--intro.txt--

Hi.*
Hello.*
Yo.*
What up?*
How are you?*

--referral.txt--

This is a referral.*
This is also a referral.*
This is a referral too.*
This is the fourth referral.*
This is The last referral.*

--body.txt--

This is a body.*
This is also a body.*
This is a body too.*
This is the fourth body.*
This is The last body.*

--closing.txt--
Have a good day.*
Bye.*
See yeah.*
Later.*
Later days.*

--wrong output--
This is The last body.This is The last referral.Later.

【问题讨论】:

  • 你能提供一些文件样本吗?我认为问题在于,当您拆分字符串时,它会生成一个空字符串 ""。这种情况经常发生。一个简单的解决方法是将其更改为 sectionString = [word for word in file.read().replace("\n", "").split("*") if word != ""]。看看这是否有效。
  • 我之前发布了错误的代码。它已被纠正。
  • 一个小技巧——在我看来,string.strip("\n")string.replace("\n","") 好一点。

标签: python random


【解决方案1】:

这是python中的常见问题。当您使用 string.split(chars) 时,python 会使用这些字符断开字符串,即使分隔符后没有任何内容。因此,例如,您的“intro.txt”将生成此列表 - ['Hi.', 'Hello.', 'Yo.', 'What up?', 'How are you?', '']。发生这种情况是因为字符串末尾有一个定界符。 Python 找到它,开始在它之后创建一个新的列表元素,但是什么也没有,因此,python 将它保留为空字符串。

如果您知道确切的文件内容,那么很容易预测空字符串将出现在哪里,您可以手动删除它们,如sectionString = sectionString[:-1]。但在大多数实际情况下,您只会知道文件格式,而不知道确切的内容。在这种情况下,如果您愿意,我在评论中提出的解决方法是清理空字符串和/或其他一些东西的最可靠和最简单的方法。

因此,将分割线更改为

sectionString = [word for word in file.split("*") if word != ""]

编辑:即使在多个分隔符在一起的情况下,如"data1*data2**data3"。 Python 会产生一个空字符串,只是不在列表的末尾而是在中间。所以,列表就像["data1","data2","","data3"]。并且可以有多个这样的空字符串。当我手动读取一些 csv 文件时,总是会发生这种情况。在列表推导式中加入条件会使结果更加可靠。

【讨论】:

    【解决方案2】:

    因为最后一个字符串以“*”结尾,所以当您进行拆分时,您将得到一个最后的空项。

    Python 3.8.10 (default, Nov 26 2021, 20:14:08) 
    [GCC 9.3.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> a = "1*2*3*4*"
    >>> a.split('*')
    ['1', '2', '3', '4', '']
    >>> 
    

    您可能会考虑 sectionString.rstrip('*').split('*'),但在那种情况下,为什么不直接使用 splitlines

    【讨论】:

    • 在 OP 的情况下,您的解决方案很棒。但在某些情况下,例如 csv 文件,字符串中间可以有多个分隔符。比如"data1,data2,,,data3,。在这种情况下,string.rstip(",") 会失败。这种情况需要手动删除所有空字符串。
    • 除非您知道要求是什么,否则说“rstrip 会失败”是不准确的。在这种情况下,他的问题是文件末尾的附加条目。也许他想在中间保留空白词。你在做一个假设。
    猜你喜欢
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多