【问题标题】:Create new list of strings from large list of strings从大字符串列表中创建新的字符串列表
【发布时间】:2020-04-21 12:17:24
【问题描述】:

假设我有一个字符串数组,它采用 YYYYMMDD 格式的日期格式。例如:

 masterlist = ['20190701', '20190702', ... '20190731'] 

假设我想创建一个包含 3 个列表的新系列,长度分别为 xyz。对于这个例子,我们可以简单地说x = 20y = 10z = 1。格式是这样的,我想遍历masterlist 中的所有元素以设置为z。从这里,我想取 20 个随机日期不包含 z 中的日期,并将它们分配给 x。最后,那些不在xz 中的日期将留给y。换句话说,任何列表都不应该有相同的日期。

例如:

z = ['20190701']
x = ['20190702', ... , '20190721']
y = ['20190722', ... , '20190731']

还有一个:

z = ['20190702']
x = ['20190701', '20190703', ..., '20190720']
y = ['20190722', ... , '20190731']

x 和/或y 之间的顺序或随机混合无关紧要,只要列表是互斥的并且共同详尽即可。

实现这一目标的最简单方法是什么?

【问题讨论】:

标签: python arrays string list match


【解决方案1】:

您可以使用集合来做到这一点(比如说我的 z=1、x=2、y=1 和 masterlist=5)

import random
masterlist = ['20190701', '20190702', '20190703', '20190704', '20190705']
z = random.sample(masterlist, 1)
x = random.sample((set(masterlist) - set(z)), 2)
y = random.sample(((set(masterlist) - set(x)) - set(z)), 1)
# z ['20190702']
# x ['20190701', '20190705']
# y ['20190704']

这是寻找集合之间的差异(它将返回第一个集合中不在第二个集合中的值),最后的数字是样本大小。

【讨论】:

  • 因此,如果我想将 Z 硬编码为 masterlist 中的第一个值(例如,z = masterlist[0])并继续执行其余代码,它将包含在 x 中。这是为什么呢?
  • 因为 masterlist[0] 是一个字符串,而不是一个列表。当您在字符串上调用set 时,它实际上将集合分解为字符串中的单个字符,因此集合类似于{'0', '9', '7', '2', '1'}。最好的故障排除方法之一是print 函数:P。我总是在编写一段代码后打印,以确保得到我应该得到的结果。
  • random.sample(masterlist, 1) 实际上仍然返回长度为 1 的列表。
【解决方案2】:

您可以通过创建要设置主列表划分的“规则”字典来做到这一点,这样您就可以在划分主列表的方式上获得动力和控制:

import random
import pprint as pp
master_list = range(0,31,1) # this is your dates list from 2019.07.01 to 2019.07.31

divided = { # also set up for applying rules of dividing the master list
    1 : 20,
    2 : 10,
    3 : 1
}


taken = []
for k,v in divided.items():
    divided[k] = random.sample([element for element in master_list if element not in taken],v)
    for t in divided[k]: taken.append(t)

pp.pprint(divided)

输出:

{1: [26, 25, 8, 22, 17, 19, 13, 7, 14, 0, 27, 18, 30, 5, 2, 6, 20, 1, 11, 9],
 2: [15, 21, 23, 28, 4, 16, 10, 24, 3, 12],
 3: [29]
}

当然,您可以在分割字典中添加另一个 key:value 来设置另一个“分隔符”。

【讨论】:

    【解决方案3】:

    您可以随机打乱列表,然后对其进行切片(替换您想要的长度):

    import random
    
    masterlist = ['20190701', '20190702', ... '20190731']
    newlist = [a for a in masterlist]
    random.shuffle(newlist)
    x = newlist[:20]
    y = newlist[20:30]
    z = newlist[-1]
    

    【讨论】:

      【解决方案4】:

      您可以只打乱主列表,然后将元素放入列表中,同时确保它们不在其他列表中。

      我创建了一个函数,该函数在检查元素是否不在某个set 中时创建一个特定长度的列表。我还假设 三个列表中您可以 有重复项,但在列表之间 没有重复项。

      def makeListWithConstraint(masterlist, newlength, constraintSet=set()):
          i = 0
          l = []
          while (len(l) < newlength): # keep going until list has desired length
              if masterlist[i] not in constraintSet:
                  l.append(masterlist.pop(i))  # pop also deletes items from the masterlist
              else:
                  i += 1
          return l
      

      那么您将在示例中使用如下函数:

      # shuffle first to ensure random
      random.shuffle(masterlist)
      
      # make constrained lists
      z_list = makeListWithConstraint(masterlist, x)
      x_list = makeListWithConstraint(masterlist, x, set(z_list))
      y_list = makeListWithConstraint(masterlist, y, set(z_list + x_list))
      

      【讨论】:

      • 我看到了d-kennetz solution,而random.sample() 是我自定义函数的一个很好的替代方案。
      猜你喜欢
      • 2013-08-11
      • 2016-02-13
      • 2011-04-20
      • 2022-11-16
      • 2019-07-07
      • 1970-01-01
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多