假设我在这样的列表中有一个元组:
>>> t = [("asdf", )]
Run Code Online (Sandbox Code Playgroud)
我知道列表总是包含一个1元组.目前我这样做:
>>> dummy, = t
>>> value, = dummy
>>> value
'asdf'
Run Code Online (Sandbox Code Playgroud)
是否有更短更优雅的方式来做到这一点?
为什么这个Scala代码:
class Test
{
def foo: (Int, String) =
{
(123, "123")
}
def bar: Unit =
{
val (i, s) = foo
}
}
Run Code Online (Sandbox Code Playgroud)
生成以下字节码bar(),构造一个新的Tuple2,将Tuple2from 传递foo()给它,然后从中获取值?
public void bar();
Code:
0: aload_0
1: invokevirtual #28; //Method foo:()Lscala/Tuple2;
4: astore_2
5: aload_2
6: ifnull 40
9: new #7; //class scala/Tuple2
12: dup
13: aload_2
14: invokevirtual #32; //Method scala/Tuple2._1:()Ljava/lang/Object;
17: aload_2
18: invokevirtual #35; //Method scala/Tuple2._2:()Ljava/lang/Object;
21: invokespecial #20; //Method scala/Tuple2."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
24: …Run Code Online (Sandbox Code Playgroud) 问题:编写一个__init__直接将集合作为参数而不是解压缩其内容的优缺点是 什么?
上下文:我正在编写一个类来处理数据库表中几个字段的数据.我遍历一些大的(约1亿行)查询结果,一次将一行传递给执行处理的类.每行作为元组从数据库中检索(或者可选地,作为字典).
讨论:假设我对三个字段感兴趣,但传递给我的类的内容取决于查询,查询由用户编写.最基本的方法可能是以下之一:
class Direct:
def __init__(self, names):
self.names = names
class Simple:
def __init__(self, names):
self.name1 = names[0]
self.name2 = names[1]
self.name3 = names[2]
class Unpack:
def __init__(self, names):
self.name1, self.name2, self.name3 = names
Run Code Online (Sandbox Code Playgroud)
以下是可能传递给新实例的行的一些示例:
good = ('Simon', 'Marie', 'Kent') # Exactly what we want
bad1 = ('Simon', 'Marie', 'Kent', '10 Main St') # Extra field(s) behind
bad2 = ('15', 'Simon', 'Marie', 'Kent') # Extra field(s) in front
bad3 = ('Simon', 'Marie') # …Run Code Online (Sandbox Code Playgroud) 在python中,当我将列表分配给另一个时,例如:
a = [1,2,3]
b = a
Run Code Online (Sandbox Code Playgroud)
现在b和指向同一个列表.现在考虑两个清单,
a = [1,2,3]
b = [4,5,6]
a,b = b,a
Run Code Online (Sandbox Code Playgroud)
现在它们如何像任何其他数据类型一样被交换,并且最终都没有指向同一个列表?
当我拥有a=1和b=2,我可以a,b=b,a这样写,a并b互相交换.
我使用这个矩阵作为数组:
[ 1, 2, 0, -2]
[ 0, 0, 1, 2]
[ 0, 0, 0, 0]
Run Code Online (Sandbox Code Playgroud)
交换numpy数组的列不起作用:
import numpy as np
x = np.array([[ 1, 2, 0, -2],
[ 0, 0, 1, 2],
[ 0, 0, 0, 0]])
x[:,1], x[:,2] = x[:,2], x[:,1]
Run Code Online (Sandbox Code Playgroud)
它产生:
[ 1, 0, 0, -2]
[ 0, 1, 1, 2]
[ 0, 0, 0, 0]
Run Code Online (Sandbox Code Playgroud)
所以x[:,1]简单地被覆盖而不是转移到x[:,2].
为什么会这样?
为什么这不起作用?:
d["a"], d["b"] = *("foo","bar")
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来实现我想要实现的目标?
我想使用一个名为 Pandas 的数据框df,它有一个 ID 列和一个包含可变数量元组的列表的列表列,所有的元组都具有相同的长度。看起来像这样:
ID list
1 [(0,1,2,3),(1,2,3,4),(2,3,4,NaN)]
2 [(Nan,1,2,3),(9,2,3,4)]
3 [(Nan,1,2,3),(9,2,3,4),(A,b,9,c),($,*,k,0)]
Run Code Online (Sandbox Code Playgroud)
我想将每个列表解包到列 'A','B','C','D' 中,代表每个元组中的固定位置。
结果应如下所示:
ID A B C D
1 0 1 2 3
1 1 2 3 4
1 2 3 4 NaN
2 NaN 1 2 3
2 9 2 3 4
3 NaN 1 2 3
3 9 2 3 4
3 A b 9 c
3 $ * k 0
Run Code Online (Sandbox Code Playgroud)
我尝试过df.apply(pd.Series(list)但失败了len,因为不同行上的列表元素不同。需要以某种方式解压到列并按 ID 转置?
当我尝试在列表理解中解压列表时:
[*parent.rules for parent in parents if hasattr(parent, "rules")]
Run Code Online (Sandbox Code Playgroud)
我收到错误:
SyntaxError: iterable unpacking cannot be used in comprehension
Run Code Online (Sandbox Code Playgroud)
虽然我知道还有其他方法可以做到这一点,但这似乎是最明显和 Pythonic 的方法。为什么 Python 不允许这种行为?
应该如何将 aiterable解包为数量不匹配的变量?
值太多:
>>> one,two = [1,2,3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
Run Code Online (Sandbox Code Playgroud)
可以忽略
>>> one,two,*_ = [1,2,3,4]
>>>
Run Code Online (Sandbox Code Playgroud)
注意:“扩展可迭代解包”仅从 Python 3 开始。关于下划线。
数据太少/变量多的相反情况如何:
>>> one,two,three = [1,2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 3, got 2)
>>>
Run Code Online (Sandbox Code Playgroud)
被处理,特别是以便分配剩余的变量None(或其他值)?
像这样的东西:
>>> one,two,three = [1,2] or None
Traceback …Run Code Online (Sandbox Code Playgroud) 这与新的 Python 3.10 beta 和新语法有关match。有没有什么方法可以检查模式是否简单地包含在可迭代中?最明显的解决方案是简单地在两侧放置两个通配符,但这会SyntaxError由于来自可迭代解包的解包语法而引发。
有没有可能的方法来做到这一点?注意:在示例中使用包装类之类的东西numbers
就可以了,只要它可以使用匹配块并且至少具有一定的可读性,但我已经尝试过这一点,但没有取得太大成功
例子:
numbers = [1, 2, 3, 5, 7, 8, 9] #does not have to be a list, could be a class if needed
match numbers:
# this just raises a SyntaxError, but I need a way to do something equivalent to this
case [*_, (5 | 6), *_]:
print("match!")
Run Code Online (Sandbox Code Playgroud) python iterable iterable-unpacking python-3.10 structural-pattern-matching
python ×9
list ×2
tuples ×2
arguments ×1
arrays ×1
dictionary ×1
group-by ×1
iterable ×1
numpy ×1
pandas ×1
python-3.10 ×1
python-3.x ×1
scala ×1