Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!rt.uk.eu.org!newsfeed.xs4all.nl!newsfeed2a.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.002 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'operator': 0.03; 'assign': 0.07; 'assignment': 0.07; 'source.': 0.07; 'cc:addr:python-list': 0.11; 'python': 0.11; 'itself.': 0.14; '20]': 0.16; 'assigns': 0.16; 'element,': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'helps!': 0.16; 'in-place': 0.16; 'ok...': 0.16; 'operation,': 0.16; 'tuple': 0.16; 'tuple,': 0.16; 'typeerror:': 0.16; 'wrote:': 0.18; 'trying': 0.19; 'things.': 0.19; 'feb': 0.22; '>>>': 0.22; 'cc:addr:python.org': 0.22; 'cc:2**0': 0.24; "i've": 0.25; 'first,': 0.26; 'this:': 0.26; 'second': 0.26; 'header:In-Reply-To:1': 0.27; 'am,': 0.29; 'returned': 0.30; 'message-id:@mail.gmail.com': 0.30; "i'm": 0.30; 'gives': 0.31; '"",': 0.31; '>>>>': 0.31; 'asks': 0.31; 'extending': 0.31; 'safely': 0.31; 'file': 0.32; 'extend': 0.32; '(most': 0.33; 'fri,': 0.33; 'problem': 0.35; "can't": 0.35; 'common': 0.35; 'point.': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'add': 0.35; 'returning': 0.36; 'so,': 0.37; 'two': 0.37; 'list': 0.37; 'list.': 0.37; 'step': 0.37; 'whatever': 0.38; 'list,': 0.38; 'recent': 0.39; 'does': 0.39; 'changed': 0.39; 'skip:p 20': 0.39; 'then,': 0.60; 'hope': 0.61; "you're": 0.61; 'back': 0.62; 'more': 0.64; '30,': 0.65; 'confusion.': 0.84; 'to:none': 0.92 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=Pdp8OGxbnCMT8rXgOk1epYqwm+QoptYLDlwyrl/jXI8=; b=vhnUrrnLuGiUojHfGXE9E1idfa4LM6QQVCEF5sRZYcmLQG7tqg1fSwbgQJ+Ps45/nd C+X53uCtLg7x03tOOkCR7XNToWvC9Tqyiu9LQJaGnDs/H4Onu5usVB5vSd5yIxHhi/XH rG7oGDUEnbMPrJcc+GDVuLhZK1zIlVCEs591AaXgyNjtH7b9OeC/9hswgAalsWoMZeiE 1tijUep6PimX6FS02omY4lT5pfrit9NC3CTXt3vupj/cV2gevj3+6RESNgLlCkXAsQjO wFgvViyiIaNmd1AM7oNfvCqhIplNTuG5O+1bOKL/UgQprZpxZc2gTa8bRBeiDUPQ2+uT K/LQ== MIME-Version: 1.0 X-Received: by 10.66.160.2 with SMTP id xg2mr15831554pab.23.1393517648307; Thu, 27 Feb 2014 08:14:08 -0800 (PST) In-Reply-To: References: Date: Fri, 28 Feb 2014 03:14:08 +1100 Subject: Re: Tuples and immutability From: Chris Angelico Cc: "python-list@python.org" Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 62 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1393517651 news.xs4all.nl 2935 [2001:888:2000:d::a6]:43419 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:67153 On Fri, Feb 28, 2014 at 3:01 AM, Eric Jacoboni wrote: > I'm using Python 3.3 and i have a problem for which i've still not found > any reasonable explanation... > >>>> a_tuple = ("spam", [10, 30], "eggs") >>>> a_tuple[1] += [20] > Traceback (most recent call last): > File "", line 1, in > TypeError: 'tuple' object does not support item assignment > > Ok... I accept this message as += is a reassignment of a_tuple[1] and a > tuple is immutable... > > But, then, why a_tuple is still modified? > >>>> a_tuple > ('spam', [10, 30, 20], 'eggs') > > I get a TypeError for an illegal operation, but this operation is still > completed? This is a common confusion. The += operator does two things. First, it asks the target to please do an in-place addition of the other operand. Then, it takes whatever result the target gives back, and assigns it back into the target. So with a list, it goes like this: >>> foo = [10, 30] >>> foo.__iadd__([20]) [10, 30, 20] >>> foo = _ Note that the second step returned a three-element list. Then the += operator stuffs that back into the source. In the case of a list, it does that addition by extending the list, and then returning itself. The putting-back-into-the-target step fails with a tuple, because a tuple's members can't be reassigned. But the list has already been changed by that point. So, when you go to look at it, you see a changed list. You can call on this behaviour more safely by using the append() or extend() methods. >>> a_tuple = ("spam", [10, 30], "eggs") >>> a_tuple[1].extend([20]) >>> a_tuple ('spam', [10, 30, 20], 'eggs') >>> a_tuple = ("spam", [10, 30], "eggs") >>> a_tuple[1].append(20) >>> a_tuple ('spam', [10, 30, 20], 'eggs') (append will add one more element, extend is roughly the same as you had). Then you're not trying to assign to the tuple, but you're still mutating the list. Hope that helps! ChrisA