1

我对在 python 中使用方法来操作列表感到非常困惑。说你有

mylist = [1,2,3,4]
mylist.append(5) #works fine, 

但是当我把

def adding(mylist):
    mylist.append(5)

print adding(mylist) #will print out the orginal list without the 5.

还,

data2 = data3 = [1,2,3]
data2 = data2 +[4]+[5]+[6] # doesn't works
data3 += [4] +[5] +[6] #works

但我很困惑他们是如何工作的。

所以我想制作一个列表(不是根据python)来操作列表的不同方式。任何人都可以帮忙吗?

4

4 回答 4

2
def adding(mylist):
    mylist.append(5)

print adding(mylist) 

你的adding方法没有返回任何东西..

在您的方法中添加一个return mylist,如下所示:-mylist.append(5)adding

def adding(mylist):
    mylist.append(5)
    return mylist
print adding(mylist)

或者你可以print adding()用这个代码替换(如果你没有返回任何东西): -

adding(mylist)
print mylist

而且,对于您的第二个问题:-

>>> data2 = data3 = [4, 5, 6]
>>> data2 = data2 + [1] + [2] + [3]
>>> print data2
[4, 5, 6, 1, 2, 3]
>>> data3 += [1] + [2] + [3]
>>> print data3
[4, 5, 6, 1, 2, 3]

实际上对我来说,它们都有效..它应该有效,你得到的输出是什么?(特别是,你期望你的输出是什么??)

于 2012-09-27T04:51:23.380 回答
2

我怀疑您希望原始代码能够正常工作的原因是因为您更熟悉使用 C++ 等语言传递引用。重要的是要注意按引用传递和按值传递的区别。了解使用的是哪一种 Python 更为重要。

简而言之,Python 实际上既不使用按引用传递,也不使用按值传递;传递是通过Python 中的对象完成的。


长答案:

可以使用 C进行值传递的示例:

#include <stdio.h>

void adding(int i) {
    i = i + 1;
}

int main() {
    int i = 0;
    adding(i);
    printf("i is %d\n", i);  // will print "i is 0"
    return 0;
}

这里, i 的值在传递给 时被复制adding()int iinside 与原始insideadding(int i)位于不同的内存位置。所以 inside ,只影响仅在 范围内已知的内存块中的值,in完全 不受影响,因为它驻留在不同的内存块中。int imain()adding()i = i + 1adding()imain()

可以使用 C++ 进行引用传递的示例:

#include <iostream>

void adding(int &i) {
    i = i + 1;
}

int main() {
    int i = 0;
    adding(i);
    std::cout << "i is " << i << std::endl;  // will print "i is 1"
    return 0;
}

这里i是通过引用传递的adding()iinside指的是与inadding()完全相同的内存块。因此,将递增到 1。imain()i


现在,让我们回到您的示例来讨论 Python(我通过猜测您的实际意思来修改 =]):

# Case 1
mylist = [1,2,3,4]
mylist.append(5)  # will print [1,2,3,4,5]

# Case 2
mylist = [1,2,3,4]
def adding(mylist):
    mylist.append(5)

adding(mylist)
print mylist  # will print [1,2,3,4,5]

# Case 3
mylist = [1,2,3,4]
def adding(mylist):
    mylist = mylist + [5]

adding(mylist)
print mylist  # will print [1,2,3,4]

# Case 4
mylist = [1,2,3,4]
def adding(mylist):
    mylist += [5]

adding(mylist)
print mylist  # will print [1,2,3,4,5]

在这里,mylist既不是通过值传递,也不是通过引用传递。它实际上是由对象传递的。

在 Python 中,mylist = [1,2,3,4]创建一个列表[1,2,3,4]并为其附加 标签 mylist。这里要注意的重要一点是 list 是一个 对象(IIRC,每个对象都是它的一个PyObject或一个扩展)。

了解这种区别将使您能够理解示例案例中的输出:

  1. 案例 1中,直接.append()[1,2,3,4]列表对象上调用以更改列表值,因此myobject附加到的对象已更改。请注意,这也是可能的,因为列表是 Python 中的可变对象。

  2. Case 2中,mylist在传递到 时不会被复制adding(),它仍然“附加”到同一个列表对象,类似于Case 1。因此,调用 .append()这个对象改变对象本身。在 之外 adding(),因为mylist仍然附加到同一个对象(即使对象已经改变了自己),我们得到输出 [1,2,3,4,5]。

  3. 案例 3中,在内部adding(),局部变量mylist附加到由[1,2,3,4]+[4]. 但是原始mylist 指向的对象从未改变过,因此,输出仍然是 [1,2,3,4].

  4. 案例 4有点棘手。在 Python 中,列表是可变的,+=充当类似 的快捷方式.extend(),它作用于调用对象本身。因此,原始对象已被修改[1,2,3,4,5]mylist仍然附加到它。可能还值得注意的是,对于元组、字符串和数字等不可变对象,+=将创建一个对象并将变量附加到它上面。


至于在 Python 中使用列表的不同方式,Fredrik Lundh 撰写的这篇文章包含了非常详尽的信息。

于 2012-09-27T23:28:15.960 回答
1

printadding(mylist)应该打印None,因为您没有从函数返回任何内容adding()

以下:

def adding(mylist):
    mylist.append(5)

test_list = range(5)

print adding(test_list)

print test_list

adding(test_list)

print test_list

产生这个输出:

None
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5, 5]

你能更具体地谈谈你的第二个例子吗?data2 原来是什么?你能指望什么?

于 2012-09-27T04:48:56.490 回答
1
def adding(mylist):
    mylist.append(5)

print adding(mylist) 

没有退货声明。

print mylist
[1,2,3,4,5]

这将打印 [1,2,3,4,5],因为它是通过引用传递的。所以即使您没有返回列表,您的 mylist 也会被修改。

data2 = data3 = [1,2,3]
data2 = data2 +[4]+[5]+[6] #Actually works 
于 2012-09-27T07:21:41.713 回答