【问题标题】:Append a String to a String in a List将字符串附加到列表中的字符串
【发布时间】:2018-09-13 02:32:02
【问题描述】:

我正在阅读一个excel表格:

import pandas as pd

df = pd.read_excel('file.xlsx', usecols = 'A,B,C')
print(df)

现在我想创建一个列表,表中的每一行都作为字符串。 此外,我想在列表中每个字符串的末尾添加一个“X”:

keylist = []
list1, list2, list3 = df['A'].tolist(), df['B'].tolist(), df['C'].tolist()

for i in zip(list1, list2, list3):
    val = map(str, i)
    keylist.append('/'.join(val))
    keylist += 'X'

print(keylist)

除了“添加 X”部分外,一切正常。这导致:

['blue/a/a1', 'X', 'blue/a/a2', 'X', ....

但我想要的是:

['blue/a/a1/X', 'blue/a/a2/X',

先谢谢了。

【问题讨论】:

  • keylist 是一个数组,所以 += 与添加数组相同。你会想做一些更类似于 val 的事情。
  • 你有没有在你的 for 循环中尝试val = map(str, i) keylist.append('/'.join(val+'X'))

标签: python string list pandas append


【解决方案1】:

您可以在每次循环中将/X 添加到list 中的最后一项:

for i in zip(list1, list2, list3):
    val = map(str, i)
    keylist.append('/'.join(val))
    keylist[-1] += '/X'

# ['blue/a/a1/X', 'blue/a/a2/X',....]

【讨论】:

    【解决方案2】:

    我认为更好的是:

    d = {'A': ['blue', 'blue', 'blue', 'red', 'red', 'red', 'yellow', 
               'yellow', 'green', 'green', 'green'],
         'B': ['a', 'a', 'b', 'c', 'c', 'c', 'd', 'e', 'f', 'f', 'g'], 
         'C': ['a1', 'a2', 'b1', 'c1', 'c2', 'c3', 'd1', 'e1', 'f1', 'f2', 'g1']}
    df = pd.DataFrame(d)
    print (df)
             A  B   C
    0     blue  a  a1
    1     blue  a  a2
    2     blue  b  b1
    3      red  c  c1
    4      red  c  c2
    5      red  c  c3
    6   yellow  d  d1
    7   yellow  e  e1
    8    green  f  f1
    9    green  f  f2
    10   green  g  g1
    
    keylist = df.apply(lambda x: '/'.join(x), axis=1).add('/X').values.tolist()
    print (keylist)
    
    ['blue/a/a1/X', 'blue/a/a2/X', 'blue/b/b1/X', 'red/c/c1/X', 'red/c/c2/X', 
     'red/c/c3/X', 'yellow/d/d1/X', 'yellow/e/e1/X', 
     'green/f/f1/X', 'green/f/f2/X', 'green/g/g1/X']
    

    或者如果只有几列:

    keylist = (df['A'] + '/' + df['B'] + '/' + df['C'] + '/X').values.tolist()
    

    一些时机

    #[110000 rows x 3 columns]
    df = pd.concat([df] * 10000, ignore_index=True)
    
    In [364]: %%timeit
         ...: (df['A'] + '/' + df['B'] + '/' + df['C'] + '/X').values.tolist()
         ...: 
    60.2 ms ± 1.04 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    
    In [365]: %%timeit
         ...: df.apply(lambda x: '/'.join(x), axis=1).add('/X').tolist()
         ...: 
    2.48 s ± 39.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    
    In [366]: %%timeit
         ...: list1, list2, list3 = df['A'].tolist(), df['B'].tolist(), df['C'].tolist()
         ...: for i in zip(list1, list2, list3):
         ...:     val = map(str, i)
         ...:     keylist.append('/'.join(val))
         ...:     keylist[-1] += '/X'
         ...: 
    192 ms ± 78.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    
    In [367]: %%timeit
         ...: df.iloc[:,0].str.cat([df[c] for c in df.columns[1:]],sep='/').tolist()
         ...: 
    61.1 ms ± 540 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    
    In [368]: %%timeit
         ...: df.assign(New='X').apply('/'.join,1).tolist()
         ...: 
    2.51 s ± 76.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    In [369]: %%timeit
         ...: ['{0}/{1}/{2}/X'.format(i, j, k) for i, j, k in df.values.tolist()]
    74.6 ms ± 2.27 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
    

    【讨论】:

    • join 在数组上工作,按照自己的方式进行操作,将给出:blue/a/a2X。如果您查看我的答案,您可以通过将其添加到 val 数组中轻松地增加它...这样 JOIN 才能正常工作。
    • @Fallenreaper 啊,但是你的会因为一个流浪的. 提供语法错误;)
    • 触摸。哈哈哈
    • @Fallenreaper - 嗯,我猜你不会投反对票,对吧?
    • 再来一次?签名...:-(
    【解决方案3】:

    您可以使用cat 字符串操作将列连接成具有指定sep 参数的单个系列。然后只需将新系列转换为列表

     df
             A  B   C
    0     blue  a  a1
    1     blue  a  a2
    2     blue  b  b1
    3      red  c  c1
    4      red  c  c2
    5      red  c  c3
    6   yellow  d  d1
    7   yellow  e  e1
    8    green  f  f1
    9    green  f  f2
    10   green  g  g1
    

    df.iloc[:,0].str.cat([df[c] for c in df.columns[1:]],sep='/').tolist()
    
    ['blue/a/a1', 'blue/a/a2', 'blue/b/b1', 'red/c/c1', 'red/c/c2', 'red/c/c3', 'yellow/d/d1', 'yellow/e/e1', 'green/f/f1', 'green/f/f2', 'green/g/g1']
    

    【讨论】:

      【解决方案4】:

      您正在 += 执行添加到该列表的密钥列表,您需要对 val 数组执行此操作。

      for i in zip(list1, list2, list3):
        val = map(str,i)
        val += 'X' # you can combine this and the above if you want to look like:
        #val = map(str, i) + 'X'
        keylist.append("/".join(val))
      print(keylist)
      

      【讨论】:

      • 为什么? val 是一个映射,所以当你使用 join 时,它会识别条目并将其添加到那里?
      • 一切都好。 :) 我只是使用 OP 使用的变量,否则 id 将其命名为更易于阅读的名称。 :)
      • 对不起,我没有仔细检查。
      【解决方案5】:

      基于pandas

      df.assign(New='X').apply('/'.join,1).tolist()
      Out[812]: ['blue/a/a1/X', 'blue/a/a2/X', 'blue/b/b1/X']
      

      【讨论】:

        【解决方案6】:

        这是使用str.format 的列表理解的一种方法:

        res = ['{0}/{1}/{2}/X'.format(i, j, k) for i, j, k in df.values.tolist()]
        
        # ['blue/a/a1/X', 'blue/a/a2/X', 'blue/b/b1/X', 'red/c/c1/X', ...]
        

        没有必要像在这个解决方案中那样,分成 3 个列表并zip 它们。

        【讨论】:

          猜你喜欢
          • 2012-09-14
          • 2012-12-05
          • 2011-01-04
          • 2016-07-03
          • 1970-01-01
          • 2012-07-12
          • 1970-01-01
          • 1970-01-01
          • 2021-04-25
          相关资源
          最近更新 更多