Python 3.8 random.choice 从文件生成的列表中进行选择时未按预期工作

Python 3.8 random.choice not working as expected when making choice from list generated from file

我正在使用 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.

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

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

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

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

所以,把分割线改成

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

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