0

假设我在下面有这个变量( id , a,b,c,d )

id  a b c d
x   2 4 5 7
y   4 5   9
z     1   2

我想从这些字符串中创建一个名为“total”的新连接变量,所以我使用了下面的代码:

total = a + ' ' + b + ' ' + c + ' ' + d

因为我不希望所有这些都彼此相邻,所以我需要在每个变量之间2457留一个空格( ) ,我的结果看起来像这样' '2 4 5 7

id  a b c d        total
x   2 4 5 7       2 4 5 7
y   4 5   9       4 5   9
z     1   2         1   2

我的问题是.. 例如@y 在 5 和 9 之间,我只想要一个空格而不是两个或者我希望我的结果看起来像这样......谁能告诉我如何做到这一点?在 SAS 中,我可以很容易地使用一些东西来压缩,不知道如何在 python 中做到这一点。

id  a b c d        total
x   2 4 5 7       2 4 5 7
y   4 5   9       4 5 9
z     1   2       1 2

希望我不会让任何人感到困惑〜,谢谢:-)

4

2 回答 2

5

使用join而不是手动连接事物的原因之一是您可以更轻松地完成更复杂的事情。

首先,如果你把你的a + ' ' + b + ' ' + c + ' ' + d变成join

' '.join((a, b, c, d))

这还没有改变任何东西。

2 4 5 7
4 5   9
  1   2

但是现在,我们怎么说“所有的非空字符串(a, b, c, d)”呢?简单的:

' '.join(x for x in (a, b, c, d) if x)

所以:

2 4 5 7
4 5 9
1 2

就是这样。

如果空值不是空字符串(或None),但是,例如' ',您需要更改测试。例如,也许:

' '.join(x for x in (a, b, c, d) if x.strip())

如果您不理解生成器表达式,以下所有内容大致等价,希望您能理解其中一个:

total = ' '.join(x for x in (a, b, c, d) if x)

total = ' '.join([x for x in (a, b, c, d) if x])

total = ' '.join(filter(bool, (a, b, c, d))

non_zero_values = []
for x in (a, b, c, d):
    if x:
        non_zero_values.append(x)
total = ' '.join(non_zero_values)

在每种情况下,想法都是一样的:我们有一个 4 个值的序列,我们通过只保留不为空的值将其过滤为 0 到 4 个值的序列。

如果我们坚持你的明确连接,这仍然是可能的,只是更难更丑:

((a + ' ') if a else '' +
 (b + ' ') if b else '' +
 (c + ' ') if c else '' +
  d if d else '')

这又给了你:

2 4 5 7
4 5 9
1 2
于 2013-01-17T20:44:26.310 回答
1

假设您的表数据位于listtuple其中每一行都将 id 值作为其第一列,并且行中给定列的值None是否为空:

totals = [' '.join(value for value in row[1:] if value is not None) for row in data]

或者,您可以将它放在一个 中dict,这可能更有用,具体取决于您以后如何使用它。

data = {'x' : {'values' : (2, 4, 5, 7)},
        'y' : {'values' : (4, 5, None, 9)},
        'z' : {'values' : (None, 1, None, 2)}}
for data_set in data.values():
    data_set['total'] = ' '.join(value for value in data_set['values'] if value is not None)
于 2013-01-17T20:40:00.623 回答