简体   繁体   English

在Python中使用生成器/“with ... as”的紧凑方式

[英]Compact way using generators/“with … as” in Python

I have the following data structure: 我有以下数据结构:

var = [['x_A_B', 1], ['x_A_C', 1], ['x_B_A', 1], ['x_B_D', 1], ['x_C_A', 1], ['x_C_D', 1], ['x_D_B', 1], ['x_D_C', 1]]

I would like to extract these values as 我想将这些值提取为

var2 = [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'D'), ('C', 'A'), ('C', 'D'), ('D', 'B'), ('D', 'C')]

Currently I use the following line 目前我使用以下行

var2 = [(item[0].split("_")[1], item[0].split("_")[2]) for item in var]

but it's tedious to write, and also calculates the same split two times. 但是编写起来很乏味,并且还会计算两次相同的split Is there a way of writing this in a compact way, maybe with keywords with ... as , something like this? 有没有办法以一种紧凑的方式写这个,也许有关键字with ... as像这样的东西?

# not working
var2 = [(u, v) with item[0].split("_") as _, u, v for item in var]

EDIT: I was looking for a more general solution, where I can use arbitrary indices of the split string with arbitrary length of substrings, I just used an improper example. 编辑:我正在寻找一个更通用的解决方案,我可以使用任意长度的子串的拆分字符串的任意索引,我只是使用了一个不恰当的例子。 See the solution I accepted. 看到我接受的解决方案。

The general case would be: 一般情况是:

[tuple(item[0].split('_')[1:3]) for item in var]

And the most general case would be: 最常见的情况是:

indices = {1,2}
[tuple([x for i, x in enumerate(item[0].split('_')) if i in indices]) for item in var]

But if you have two indices that are one next to another this would be too much. 但是如果你有两个一个接一个的索引,那就太多了。

Why even use split ? 为什么甚至使用split You know the exact indices of the letters you want. 你知道你想要的字母的确切索引。

>>> var = [['x_A_B', 1], ['x_A_C', 1], ['x_B_A', 1], ['x_B_D', 1], ['x_C_A', 1], ['x_C_D', 1], ['x_D_B', 1], ['x_D_C', 1]]
>>> [(x[0][2], x[0][4]) for x in var]
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'D'), ('C', 'A'), ('C', 'D'), ('D', 'B'), ('D', 'C')]

I am interested in a more general case, suppose there can be 'x_word1_word2' variable names. 我对更一般的情况感兴趣,假设可以有'x_word1_word2'变量名。

Well in that case internet_user gave you the solution in the comments. 那么在这种情况下,internet_user在评论中为您提供了解决方案。

>>> var = [['x_A_B', 1], ['x_word1_word2']]
>>> [tuple(x[0].rsplit('_', 2)[1:]) for x in var]
[('A', 'B'), ('word1', 'word2')]

(I used rsplit constrained to two splits for a very minor efficiency improvement.) (我使用rsplit约束了两个分割,以提高效率。)

The other answers already talk about your specific case. 其他答案已经谈到了你的具体案例。 In the more general case, if you're observing that the same value appears multiple times in a comprehension... 在更一般的情况下,如果你观察到相同的值在理解中多次出现......

var2 = [(item[0].split("_")[1], item[0].split("_")[2]) for item in var]
        ^                       ^

and you'd like to avoid this repetition. 而且你想避免这种重复。 Is that about right? 那是对的吗?

One way is to use a nested loop, but that's really a code golfing trick... 一种方法是使用嵌套循环,但这真的是一个代码高尔夫球技巧......

[(parts[1], parts[2] for item in var for parts in [item[0].split("_")]]
# or 
[(a, b) for item in var for (_, a, b) in [item[0].split("_")]]

but yeah, that wouldn't pass code review... 但是,那不会通过代码审查......

How about writing a function instead? 如何编写函数呢?

def extract_parts(item):
    parts = item[0].split("_")
    return parts[1], parts[2]

[extract_parts(item) for item in var]
# or:
map(extract_parts, var)

To answer your question with a similar approach to your example, and including your comment : 使用与您的示例类似的方法回答您的问题,并包括您的评论

Yes that works in this case, @internet_user also suggested this. 是的,在这种情况下有效,@ internet_user也建议这样做。 But what if the indices I need are not consecutive, ie I need 0 and 2? 但是如果我需要的指数不是连续的,即我需要0和2呢?

The with...as... syntax is for context managers, which has a totally different use. with...as...语法用于上下文管理器,它具有完全不同的用途。 However, a work-around is to use for-loop unpacking. 但是,解决方法是使用for-loop解包。

var = [['x_A_B', 1], ['x_A_C', 1], ['x_B_A', 1], ['x_B_D', 1], ['x_C_A', 1], ['x_C_D', 1], ['x_D_B', 1], ['x_D_C', 1]]

var2 = [(u, v) for item in var for _, u, v in (item[0].split("_"), )]

print(var2)

You can use: 您可以使用:

[tuple(x[0].split('_')[1:]) for x in var]

out: [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'D'), ('C', 'A'), ('C', 'D'), ('D', 'B'), ('D', 'C')]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM