471,123 Members | 873 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,123 software developers and data experts.

f---ing typechecking

Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>(1,)+[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "list") to tuple
>>[1]+(1,)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
>>>
Its ugly and boring.
Feb 14 '07 #1
43 1360

Sergey Dorofeev wrote:
Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>(1,)+[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "list") to tuple
>[1]+(1,)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
>>

Its ugly and boring.
what?
for me it works fine:
>>(1,)+tuple([1])
(1, 1)
>>[1]+list((1,))
[1, 1]

also
>>L=[1]
L.extend((1,))
L
[1, 1]

Feb 14 '07 #2
Sergey Dorofeev wrote:
Python 2.5 (r25:51908, Sep 19 2006, 09:52:17) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>>>(1,)+[1]

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "list") to tuple
>>>>[1]+(1,)

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
Its ugly and boring.

Agreed. This would be similar to:

py1 + 1.0

Traceback: can only add int to int. Etc.

But then again, the unimaginative defense would be that it wouldn't be
python if you could catentate a list and a tuple.

James
Feb 14 '07 #3
hg
Its ugly and boring.

It's rude, unnecessary _and_ boring
Feb 14 '07 #4
Szabolcs Nagy wrote:
>>>L=[1]
L.extend((1,))
L
[1, 1]
Are list.extend() and list concatenation supposed to behave differently?
I always thought concatenation was just shorthand for calling extend().

However the following seems to work:
>>L = [1]
L += (2,)
L
[1, 2]

It seems like the '+' operator for lists should accept any iterable for
the right side argument to be consistent with extend() and the '+='
operator.

-Farshid
Feb 14 '07 #5

"James Stroud" <js*****@mbi.ucla.eduwrote in message
news:eq**********@zinnia.noc.ucla.edu...
>>>>>[1]+(1,)

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
Its ugly and boring.

Agreed. This would be similar to:

py1 + 1.0

Traceback: can only add int to int. Etc.

But then again, the unimaginative defense would be that it wouldn't be
python if you could catentate a list and a tuple.
Maybe, but I don't think that it is best side of the languague.
If we want constant objects like tuple why not to specify it explicitly?
If we want lists as dict keys, why not to use copy-on-write?
Feb 14 '07 #6

Concatenating tuples and lists seems logical if you think of tuples as
sequences. If you think of them more like Pascal records or C structs
instead (I believe that's Guido's perspective on tuples) then it makes no
sense at all.

Skip

Feb 14 '07 #7
sk**@pobox.com wrote:
Concatenating tuples and lists seems logical if you think of tuples as
sequences. If you think of them more like Pascal records or C structs
instead (I believe that's Guido's perspective on tuples) then it makes no
sense at all.

Skip
Then iterating over them makes no sense?

James
Feb 14 '07 #8
>Concatenating tuples and lists seems logical if you think of tuples
as sequences. If you think of them more like Pascal records or C
structs instead (I believe that's Guido's perspective on tuples) then
it makes no sense at all.
JamesThen iterating over them makes no sense?

I agree that tuples are a bit schizophrenic. They really are sequences from
an implementation standpoint, but from a logical standpoint it's maybe best
not to think of them that way.

That said, this:

for x in (1,2,3):
pass

is a skosh faster (perhaps an immeasurably small skosh) than this:

for x in [1,2,3]:
pass

so people will probably continue to use tuples instead of lists in these
sorts of situations.

For an example of the struct-ness of a tuple consider the output of os.stat:
>>import os
s = os.stat("/etc/hosts")
s
(33188, 34020475L, 234881029L, 1, 0, 0, 214L, 1170562950, 1124700602, 1142602578)
>>s.st_mtime
1124700602.0
>>s[0]
33188
>>type(s)
<type 'posix.stat_result'>

It's effectively a tuple with field names. I don't know when the switch
occurred (it's in 2.2, as far back as my built interpreter versions
currently go), but back in the day os.stat used to return a plain old tuple.

I have no idea if the schizophrenic personality of tuples will improve with
drugs^H^H^H^H^H Python 3, but I wouldn't be at all surprised if it did.

Skip
Feb 15 '07 #9
On Wed, 14 Feb 2007 13:25:21 -0800, James Stroud wrote:
But then again, the unimaginative defense would be that it wouldn't be
python if you could catentate a list and a tuple.
Since lists and tuples are completely different objects with completely
different usages, what should concatenating a list and a tuple give?
Should it depend on the order you pass them?

1.0 + 1 == 1 + 1.0 for very good reasons: we consider (for pragmatic
reasons to do with loss of significant digits) that floats coerce ints
into floats rather than the other way around. But what should lists and
tuples do?

From the Zen of Python:
"In the face of ambiguity, refuse the temptation to guess."

--
Steven D'Aprano

Feb 15 '07 #10
Steven D'Aprano wrote:
On Wed, 14 Feb 2007 13:25:21 -0800, James Stroud wrote:

>>But then again, the unimaginative defense would be that it wouldn't be
python if you could catentate a list and a tuple.


Since lists and tuples are completely different objects with completely
different usages, what should concatenating a list and a tuple give?
Should it depend on the order you pass them?
Is that a guess or just common sense?
1.0 + 1 == 1 + 1.0 for very good reasons: we consider (for pragmatic
reasons to do with loss of significant digits) that floats coerce ints
into floats rather than the other way around. But what should lists and
tuples do?

From the Zen of Python:
"In the face of ambiguity, refuse the temptation to guess."
Do you guess with __add__ and __radd__?

James
Feb 15 '07 #11
sk**@pobox.com wrote:
>Concatenating tuples and lists seems logical if you think of tuples
>as sequences. If you think of them more like Pascal records or C
>structs instead (I believe that's Guido's perspective on tuples) then
>it makes no sense at all.

JamesThen iterating over them makes no sense?

I agree that tuples are a bit schizophrenic. They really are sequences from
an implementation standpoint, but from a logical standpoint it's maybe best
not to think of them that way.

That said, this:

for x in (1,2,3):
pass

is a skosh faster (perhaps an immeasurably small skosh) than this:

for x in [1,2,3]:
pass

so people will probably continue to use tuples instead of lists in these
sorts of situations.

For an example of the struct-ness of a tuple consider the output of os.stat:
>>import os
>>s = os.stat("/etc/hosts")
>>s
(33188, 34020475L, 234881029L, 1, 0, 0, 214L, 1170562950, 1124700602, 1142602578)
>>s.st_mtime
1124700602.0
>>s[0]
33188
>>type(s)
<type 'posix.stat_result'>

It's effectively a tuple with field names. I don't know when the switch
occurred (it's in 2.2, as far back as my built interpreter versions
currently go), but back in the day os.stat used to return a plain old tuple.

I have no idea if the schizophrenic personality of tuples will improve with
drugs^H^H^H^H^H Python 3, but I wouldn't be at all surprised if it did.

Skip
The arguments for how tuples behave are all very compelling and indeed I
keep them in mind when I code--careful not to confuse their uses. The
problem is that, to the uninitiated, they are redundant and are often
used interchangably. Also, it is very easy for the uninitiated to create
highly functional code in python, and so we get many hybrid uses and
confusion. I increasingly come to the decision to avoid tuples
altogether because, eventually, you end up turning them into lists
anyway and so they begin to represent extra overhead--although its
always fun to try to identify cases when they might provide some value.

James
Feb 15 '07 #12
On Wed, 14 Feb 2007 19:45:14 -0800, James Stroud wrote:
Steven D'Aprano wrote:
>On Wed, 14 Feb 2007 13:25:21 -0800, James Stroud wrote:

>>>But then again, the unimaginative defense would be that it wouldn't be
python if you could catentate a list and a tuple.


Since lists and tuples are completely different objects with completely
different usages, what should concatenating a list and a tuple give?
Should it depend on the order you pass them?

Is that a guess or just common sense?
Sorry, is *what* a guess?

Conceptually, ints are a subset of floats (they certainly are in pure
mathematics). Automatic coercions from ints to floats makes sense;
automatic coercions the other way rarely do -- should you round up or
round down or truncate? What is right in one application is not right for
another.

Lists and tuples, on the other hand, are conceptually two distinct data
types. Adding a list to a tuple is no more sensible than adding a list to
a string -- just because they're both sequences doesn't mean adding them
together is meaningful.

>1.0 + 1 == 1 + 1.0 for very good reasons: we consider (for pragmatic
reasons to do with loss of significant digits) that floats coerce ints
into floats rather than the other way around. But what should lists and
tuples do?

From the Zen of Python:
"In the face of ambiguity, refuse the temptation to guess."

Do you guess with __add__ and __radd__?
No. If there is an obviously correct behaviour for addition (like with
ints and floats) then I coerce the objects appropriately. If there is no
obviously correct behaviour, I refuse to guess.

The user's expected behaviour for [1] + (1,) might be to return a list, or
it might be to return a tuple. Since there is no obviously correct
behaviour, the right thing to do is to refuse to guess.
--
Steven D'Aprano

Feb 15 '07 #13
Steven D'Aprano wrote:
On Wed, 14 Feb 2007 19:45:14 -0800, James Stroud wrote:
>>Steven D'Aprano wrote:
>>>Since lists and tuples are completely different objects with completely
different usages, what should concatenating a list and a tuple give?
Should it depend on the order you pass them?

Is that a guess or just common sense?

Sorry, is *what* a guess?
That it should depend on order.
Conceptually, ints are a subset of floats (they certainly are in pure
mathematics). Automatic coercions from ints to floats makes sense;
automatic coercions the other way rarely do -- should you round up or
round down or truncate? What is right in one application is not right for
another.

Lists and tuples, on the other hand, are conceptually two distinct data
types. Adding a list to a tuple is no more sensible than adding a list to
a string -- just because they're both sequences doesn't mean adding them
together is meaningful.
>>Do you guess with __add__ and __radd__?

No. If there is an obviously correct behaviour for addition (like with
ints and floats) then I coerce the objects appropriately. If there is no
obviously correct behaviour, I refuse to guess.

The user's expected behaviour for [1] + (1,) might be to return a list, or
it might be to return a tuple. Since there is no obviously correct
behaviour, the right thing to do is to refuse to guess.
I guess we differ on what is obvious. This seems obvious to me:

[1] + (1,) =[1, 1]
(1,) + [1] =(1, 1)

simply becuase the operand on the left should take precendence because
its "__add__" is called and its "__add__" returns a list. In essence, as
we know the obviously correct behavior for __add__ and __radd__, then it
would be the obviously correct behavior that the above would follow.

I would venture to guess that most people would intuitively consider the
above behavior correct, simply because the information content
difference between a list versus a tuple is non-existent (outside of the
information that one is a list and the other a tuple). Why would their
types dictate coercion? With ints and floats, as you point out, the
reasons that type dictates coercion are obvious and mathematical. Thus,
for tuples and lists, it wouldn't make sense to consider one type taking
precendence over the other, so we fall back to position, which seems to
be the common sense approach.

James
Feb 15 '07 #14
On Wed, 14 Feb 2007 22:21:43 -0800, James Stroud wrote:
>The user's expected behaviour for [1] + (1,) might be to return a list, or
it might be to return a tuple. Since there is no obviously correct
behaviour, the right thing to do is to refuse to guess.

I guess we differ on what is obvious. This seems obvious to me:

[1] + (1,) =[1, 1]
(1,) + [1] =(1, 1)

simply becuase the operand on the left should take precendence because
its "__add__" is called and its "__add__" returns a list.
But that's data dependent. When you call

[1] + MyTuple(1)

your MyTuple.__radd__ will be called first, not the list's __add__.
In essence, as
we know the obviously correct behavior for __add__ and __radd__, then it
would be the obviously correct behavior that the above would follow.
But we don't know the obviously correct behaviour. Why should list.__add__
return a list if the other operand is a tuple? You're assuming what I'm
asking you to justify.

int.__add__ doesn't necessarily return an int. Why should lists
be different?

I would venture to guess that most people would intuitively consider the
above behavior correct,
I dare say you are right for *some* people. After all, Perl and other
weakly-typed languages try to coerce virtually all types. I doubt it is
a majority.

simply because the information content
difference between a list versus a tuple is non-existent (outside of the
information that one is a list and the other a tuple). Why would their
types dictate coercion?
But that's what you're doing -- implicit coercion.

[1] + (1,) == [1] + [1]
(1,) + [1] == (1,) + (1,)

I don't believe there is any justification for doing such coercion for
lists and tuples.

With ints and floats, as you point out, the
reasons that type dictates coercion are obvious and mathematical. Thus,
for tuples and lists, it wouldn't make sense to consider one type taking
precendence over the other, so we fall back to position, which seems to
be the common sense approach.
I would say the commonsense approach is to refuse the temptation to guess
in the face of ambiguity. Since neither coercing lists to tuples nor
tuples to lists is more obviously correct, raising an exception is the
sensible behaviour. Let the caller choose the correct coercion to use.

--
Steven D'Aprano

Feb 15 '07 #15

<sk**@pobox.comwrote in message
news:ma***************************************@pyt hon.org...
It's effectively a tuple with field names. I don't know when the switch
occurred (it's in 2.2, as far back as my built interpreter versions
currently go), but back in the day os.stat used to return a plain old
tuple.
posix.stat_result is CLASS, not regular tuple.
classes is the only way in python to approximate records/structs (may be
dict can be considered as record too, if we agree with strange syntaxis).
To consider tuples as struct, one must have a GREAT imagination, as tuples
functionally are _arrays_, with only difference from lists as freezeness -
the have NO filed names.
I have no idea if the schizophrenic personality of tuples will improve
with
drugs^H^H^H^H^H Python 3, but I wouldn't be at all surprised if it did.
I think the best thing is to be more democratic when asked to add two arrays
:)
Feb 15 '07 #16
Since tuples are immutable, I think of them as fixed data objects with
some simple sequential structure, as opposed to lists which are much
more dynamically accessible/updateable data containers. Back in my
relational database design days, I sometimes had to create a primary
key for a table by combining values stored in two or more columns -
neither column value alone was unique, but the combination of them
was, and so made a good retrieval index. In Python, such data pairs
would be ideally represented with tuples, in support of in-memory data
cacheing or tree indexing - for a given record, the values don't
change, so the immutability of their tupleness doesn't get in the way.

In similar vein, I've used tuples internally in my Python code as
cache keys for function memoizing. They are WORM structures - write
once, read many - built to represent the cache value, but never
updated.

With this idea of tuples as a data structure, I could reasonably
interpret this:

(1,"abc",3) + [1]

to result in (1,"abc",3,[1]) just as well as (1,"abc",3,1). But
instead of just picking one, Python complains about this, and so
forces me to explicitly use

(1,"abc",3) + tuple([1])

or

(1,"abc",3) + ([1],)

I don't think tuples are just an academic curiosity, as your post
seems to suggest.

-- Paul

Feb 15 '07 #17
On 2/15/07, James Stroud <js*****@mbi.ucla.eduwrote:
I guess we differ on what is obvious. This seems obvious to me:

[1] + (1,) =[1, 1]
(1,) + [1] =(1, 1)
I agreed with you up to this point. But this seems more obvious to me:

[1] + (1,) =[1, 1]
(1,) + [1] =[1, 1]

In other languages and situations, types are widened, 1 + 1.0 = 1.0 +
1.0. And list is "wider" than tuple.

--
mvh Björn
Feb 15 '07 #18
James Stroud wrote:
sk**@pobox.com wrote:
>Concatenating tuples and lists seems logical if you think of tuples as
sequences. If you think of them more like Pascal records or C structs
instead (I believe that's Guido's perspective on tuples) then it makes no
sense at all.

Skip

Then iterating over them makes no sense?
Given Guido's assertions about the nature of the tuple, no it doesn't.
But I seriously doubt that 3.0 will remove the iterable interface from
tuples, despite its impurity.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
Blog of Note: http://holdenweb.blogspot.com
See you at PyCon? http://us.pycon.org/TX2007

Feb 15 '07 #19
BJörn Lindqvist wrote:
On 2/15/07, James Stroud <js*****@mbi.ucla.eduwrote:
>I guess we differ on what is obvious. This seems obvious to me:

[1] + (1,) =[1, 1]
(1,) + [1] =(1, 1)

I agreed with you up to this point. But this seems more obvious to me:

[1] + (1,) =[1, 1]
(1,) + [1] =[1, 1]

In other languages and situations, types are widened, 1 + 1.0 = 1.0 +
1.0. And list is "wider" than tuple.
They are widened by information content, not functionality. Tuples don't
have any more information content than lists.
Feb 15 '07 #20
Steven D'Aprano wrote:
On Wed, 14 Feb 2007 22:21:43 -0800, James Stroud wrote:
>>The user's expected behaviour for [1] + (1,) might be to return a list, or
it might be to return a tuple. Since there is no obviously correct
behaviour, the right thing to do is to refuse to guess.
I guess we differ on what is obvious. This seems obvious to me:

[1] + (1,) =[1, 1]
(1,) + [1] =(1, 1)

simply becuase the operand on the left should take precendence because
its "__add__" is called and its "__add__" returns a list.

But that's data dependent. When you call

[1] + MyTuple(1)

your MyTuple.__radd__ will be called first, not the list's __add__.
OK. With this you are beginning to convince me. Yes, I would want my
__radd__ called in this case (which is a form of mind-reading, but
necessary and convenient)--so your point is how might python read one's
mind given list and tuple. You got me there.

But you must agree that I am not an easy turn.
Feb 15 '07 #21
Paul McGuire wrote:
Since tuples are immutable, I think of them as fixed data objects with
some simple sequential structure, as opposed to lists which are much
more dynamically accessible/updateable data containers. Back in my
relational database design days, I sometimes had to create a primary
key for a table by combining values stored in two or more columns -
neither column value alone was unique, but the combination of them
was, and so made a good retrieval index. In Python, such data pairs
would be ideally represented with tuples, in support of in-memory data
cacheing or tree indexing - for a given record, the values don't
change, so the immutability of their tupleness doesn't get in the way.

In similar vein, I've used tuples internally in my Python code as
cache keys for function memoizing. They are WORM structures - write
once, read many - built to represent the cache value, but never
updated.
With this idea of tuples as a data structure, I could reasonably
interpret this:

(1,"abc",3) + [1]

to result in (1,"abc",3,[1]) just as well as (1,"abc",3,1). But
instead of just picking one, Python complains about this, and so
forces me to explicitly use

(1,"abc",3) + tuple([1])

or

(1,"abc",3) + ([1],)

I don't think tuples are just an academic curiosity, as your post
seems to suggest.

-- Paul
Were lists implemented as efficiently as tuples in terms of memory and
speed, there would be no difference except the academic one--which is
perhaps important.

Actually, I must admit that I use them and their implicit meanings all
the time in my code (as proof, notice in the "any way to create a
table-like object?" thread how I specify column headers--its for a
reason I use tuple in the example because the resulting data structures
will be ordered according to the tuple passed--of course, I refuse to
enforce this via "ugly and boring" type checking). For the most part, I
ignore the implementation differences and draw the distinction at their
semantics.

Also, risking getting a reputation for being overly contentious, I think
your argument falls apart in the latter half of your post because "+",
as far as I can tell with python sequences, is used to mean catenate
exclusively and not append, which is what you suggest as a possibility.

Anyway, D'Arpano made an excellent point with a good mind-reading
example and so I understand the design decision regarding catenation of
tuples and lists more clearly now. I'm still not sure I like it, but
there is no accounting for taste.

James
Feb 15 '07 #22
On 15 feb, 07:21, James Stroud <jstr...@mbi.ucla.eduwrote:
I guess we differ on what is obvious. This seems obvious to me:

[1] + (1,) =[1, 1]
(1,) + [1] =(1, 1)

simply becuase the operand on the left should take precendence because
its "__add__" is called and its "__add__" returns a list. In essence, as
we know the obviously correct behavior for __add__ and __radd__, then it
would be the obviously correct behavior that the above would follow.
Given those obviouses, the following seems to me:

[1] + (1,) =[1, (1,)]

That's the trouble with obvious -- my obvious may not be so obvious to
you (and vice versa). That's why the Zen of Python says "In the face
of ambiguity, refuse the temptation to guess." (Although it also says
"Flat is better than nested", but I'll ignore that for now.)

Basically -- if you want Perl, you know where to find it ;-)

Marc

Feb 15 '07 #23

Sergeyposix.stat_result is CLASS, not regular tuple.

I believe it morphed from being a tuple though. I wasn't suggesting that
there is some other way to approximate records. I was trying to demonstrate
the use of a tuple as a record. It eventually became so compelling that a
new struct_time type was created. It works both like a tuple as a class.

The notion of tuples as records in Python is not new:

http://mail.python.org/pipermail/pyt...er/thread.html

Search for "super tuples".

Skip
Feb 15 '07 #24
On 2007-02-15, Paul McGuire <pt***@austin.rr.comwrote:
Since tuples are immutable, I think of them as fixed data objects with
some simple sequential structure, as opposed to lists which are much
more dynamically accessible/updateable data containers.
Me, too. There are plenty of things that aren't strictly a
sequence, but which you sometimes want to iterate over anyhow.
If I had a set of fast, overpriced luxury cars in my garage, I
would sometimes want to do something to each one (like wash
them), even though they really aren't in any sequence.

Dictionary keys are the same sort of thing. Even though they
aren't in any sequence, it's still useful to iterate over them.

--
Neil Cerutti
Feb 15 '07 #25
On 2007-02-14, Farshid Lashkari <no@spam.comwrote:
Szabolcs Nagy wrote:
>>>>L=[1]
L.extend((1,))
L
[1, 1]

Are list.extend() and list concatenation supposed to behave
differently? I always thought concatenation was just shorthand
for calling extend().
They are different. list.extend() mutates the list, returning
None, while the + operator returns a new, concatenated list.

+= on the other hand works very similarly to list.extend().
However:
>>[1, 2].extend([3])
[1, 2] += [3]
SyntaxError: augmented assign to list literal or comprehension not possible
It seems like the '+' operator for lists should accept any
iterable for the right side argument to be consistent with
extend() and the '+=' operator.
+= will only perform the operation in place "whenever possible",
so there are objects for which a conversion to .extend wouldn't
work, and you'd get an actual call of the + operation followed by
the assignment operation.

--
Neil Cerutti
I don't know what to expect right now, but we as players have to do what we've
got to do to make sure that the pot is spread equally. --Jim Jackson
Feb 15 '07 #26
James Stroud <js*****@mbi.ucla.eduwrites:
I increasingly come to the decision to avoid tuples altogether
because, eventually, you end up turning them into lists anyway
I don't. I end up extracting them to separate variables.
>>foo = (12, None, "spam")
# ...
# much code, perhaps passing foo around as parameter
# ...
(bar, baz, wibble) = foo
# code using bar, baz, and/or wibble
If they are eventually extracted to lists, then it generally makes no
sense for them ever to begin as a tuple.

--
\ "I have an answering machine in my car. It says, 'I'm home now. |
`\ But leave a message and I'll call when I'm out.'" -- Steven |
_o__) Wright |
Ben Finney

Feb 15 '07 #27

Sergeyposix.stat_result is CLASS, not regular tuple.
>I believe it morphed from being a tuple though. I wasn't suggesting
that
SergeyIt it morphed, the tuple nature of it is just history now.

No, it is still full of tuple-fu:
>>import os
s = os.stat("/etc/hosts")
s
(33188, 92111L, 26738688L, 1, 0, 1, 355L, 1171570459, 1164401316,
1171087243)
>>type(s)
<type 'posix.stat_result'>
>>s.st_mtime
1164401316
>>s[0:3]
(33188, 92111L, 26738688L)
>>s[4:] + s[0:3]
(0, 1, 355L, 1171570459, 1164401316, 1171087243, 33188, 92111L, 26738688L)
>>type(s[4:] + s[0:3])
<type 'tuple'>
>The notion of tuples as records in Python is not new:
http://mail.python.org/pipermail/pyt...er/thread.html
Search for "super tuples".
SergeyDid it go beyond just talking?

Raymond Hettinger just proposed adding a pure Python implementation to
Python 2.6. The version he's been using for about a year is here:

http://aspn.activestate.com/ASPN/Coo.../Recipe/500261

SergeyWe can think about tuples anything, but are they something other
Sergeythan freezed lists? We can index them, slice, iterate,
Sergeymap/redice/filter, can cast (fuckin C!) to lists and back -
Sergeywhat the difference?? "Tuples is similar to records" - I think
Sergeythis is just topological artefact, generated when python was
Sergeycompared with some other languague :)

The fact that tuples and lists share so many implementation details makes
people think of tuples as immutable lists. That view has its uses (allowing
you to pretend that you can use lists as dictionary keys or take advantage
of the compile-time allocation of tuples of constants, for example), but I
don't think that makes the view of tuples as records a "topological
artifact". I'm not sure where you believe Python was compared to some other
language. My original comment was that tuples could be thought of more like
C structs or Pascal records. That was an analogy, not a language
comparison.

Sergeyclasses have sintactically and functionally overcame
Sergeyrecords/structs - why to drag to the same role tuples, that have
Sergeynot initially any feature of record?

They have a number of record-like features. They are relatively compact
(unlike class instances), once instantiated they can't be extended (unlike
lists or class instances in the common case). They just don't yet have
named attributes.

Skip
Feb 15 '07 #28
sk**@pobox.com writes:
My original comment was that tuples could be thought of more like
C structs or Pascal records.
Should f(*args) receive a list rather than a tuple arg?
Feb 15 '07 #29
In article <7x************@ruckus.brouhaha.com>,
Paul Rubin <http://ph****@NOSPAM.invalidwrote:
sk**@pobox.com writes:
My original comment was that tuples could be thought of more like
C structs or Pascal records.

Should f(*args) receive a list rather than a tuple arg?
No, clearly not. Function parameters are good example
of exactly what tuples are about, with some extra struct/dict
stuff for emphasis.

If t is a valid argument tuple for function f, then can t[1:]
also be a valia argument tuple for function f?

For ordinary functions without special argument handling, no.
We know that without having to know anything about t, and not
much about f. This is characteristic of tuple applications.

Donn Cave, do**@u.washington.edu
Feb 15 '07 #30
Donn Cave <do**@u.washington.eduwrites:
If t is a valid argument tuple for function f, then can t[1:]
also be a valid argument tuple for function f?

For ordinary functions without special argument handling, no.
We know that without having to know anything about t, and not
much about f. This is characteristic of tuple applications.
I'm not sure what you're saying. The current situation is if I say

def f(*args):
print args

f (1,2,3,4,5,6,7)

f receives a 7-element tuple, but if I say

f (8, 9, 10)

f receives a 3-element tuple.

I'm asking whether f should receive a list instead. I think that is
more in keeping with the notion of a tuple being like a structure
datatype. How can there be a structure datatype with an unpredictable
number of members?

It might have come across as a different question-sorry for any
confusion.
Feb 15 '07 #31
On Feb 15, 5:21 pm, Paul Rubin <http://phr...@NOSPAM.invalidwrote:
How can there be a structure datatype with an unpredictable
number of members?

It might have come across as a different question-sorry for any
confusion.
This may be where the "tuple is like a struct" analogy isn't so good,
and "tuple is like a list but immutable" is better.

In both of your examples, the caller of f() sent a fixed list of
arguments: (1,2,3,4,5,6,7) in the first case and (8,9,10) in the
second. Internally I bet the compiler wants to clean up that same
list of those same args when f() is finished.

Just as a thought experiment, do this for yourself. Implement f as:

def f(*args):
args = list(args)
print args

Now what is it you want to do with args that you can't do with it as a
tuple? Do you want some form of communication back to the caller to
occur, for example? Maybe some kind of pass-by-ref instead of pass-by-
value?

-- Paul


Feb 16 '07 #32
"Paul McGuire" <pt***@austin.rr.comwrites:
Now what is it you want to do with args that you can't do with it as a
tuple?
I'm ok with it being a tuple, but I'm not so wed to the notion that
tuples are record structures. I think it would be lame to not be able
to iterat through the arg list, for example.
Feb 16 '07 #33
In article <7x************@ruckus.brouhaha.com>,
Paul Rubin <http://ph****@NOSPAM.invalidwrote:
Donn Cave <do**@u.washington.eduwrites:
If t is a valid argument tuple for function f, then can t[1:]
also be a valid argument tuple for function f?

For ordinary functions without special argument handling, no.
We know that without having to know anything about t, and not
much about f. This is characteristic of tuple applications.

I'm not sure what you're saying. The current situation is if I say

def f(*args):
print args

f (1,2,3,4,5,6,7)

f receives a 7-element tuple, but if I say

f (8, 9, 10)

f receives a 3-element tuple.
OK, and of course

- f has some implementation which assigns meaning to each
parameter, according to its position.

- it does this by assigning names to those positions (this isn't
essential to my point, but reinforces the struct analogy)

For any basic, no-tricks implementation of f, the second application
is going to have problems:

- fourth and following positions have no actual parameters

- if you meant to portray (8, 9, 10) as t[4:], where t is
(_, _, _, _, 8, 9, 10), following my proposition above,
then it should be clear that inasmuch as t[4] for example
has some meaning in terms of f, one cannot preserve this
meaning in a smaller slice of t. Please think about it,
because I do not intend to try to explain this again.

So the parameters of f form a sort of type -- an ordered sequence
of values, where each item has a different meaning according to
its absolute position in the sequence, and where a name is assigned
(by at least f and optionally by its caller) to each position.
This type can be represented by many possible values, but we can
observe that just as a matter of principle, for any value of this
type, a smaller slice is not also of this type.

Of course the word "type" above is about something that is not
formally implemented in Python, so you can obtusely quibble about
whether it's a type or not, but the constraints are real.
I'm asking whether f should receive a list instead. I think that is
more in keeping with the notion of a tuple being like a structure
datatype. How can there be a structure datatype with an unpredictable
number of members?
Unpredictable? How do you manage to write functions in this case?
Are all your formal parameter lists like (*a), with logic to deal
with the variable lengths? But even that wouldn't by itself make
your point. Any experienced C programmer is likely to have "subtyped"
a struct, adding one or more values to the end of the parent struct,
so the value can be passed to functions that expect the parent type.
Variable length isn't strictly foreign to struct types.

Donn Cave, do**@u.washington.edu
Feb 16 '07 #34
Donn Cave <do**@u.washington.eduwrites:
Unpredictable? How do you manage to write functions in this case?
Are all your formal parameter lists like (*a), with logic to deal
with the variable lengths?
I'm thinking of functions like printf, which take a variable number of
args and don't assign them into variables by position.
Feb 16 '07 #35
In article <7x************@ruckus.brouhaha.com>,
Paul Rubin <http://ph****@NOSPAM.invalidwrote:
Donn Cave <do**@u.washington.eduwrites:
Unpredictable? How do you manage to write functions in this case?
Are all your formal parameter lists like (*a), with logic to deal
with the variable lengths?

I'm thinking of functions like printf, which take a variable number of
args and don't assign them into variables by position.
I don't really see why you're thinking of them, but if
you look at how they do it, you'll see that they use some
run time magic to work as if they were written as conventional
functions. This invariably involves some accessory data, like
printf's format string, that in effect tells the function its
parameter implementation at run time - including number of
parameters, since you can't tell even that from standard args
data as far as I know. What this proves is that you can implement
an argument list at run time, but it by no means changes the
nature of the argument list as a sequence.

Donn Cave, do**@u.washington.edu
Feb 17 '07 #36
Donn Cave <do**@u.washington.eduwrites:
What this proves is that you can implement
an argument list at run time, but it by no means changes the
nature of the argument list as a sequence.
Right, it's treated as a sequence rather than a record structure.
So is that consistent with the "tuples are record structures" view,
as opposed to the "tuples are immutable lists" view?
Feb 17 '07 #37
On 15 Feb 2007 16:04:14 -0800, Paul McGuire <pt***@austin.rr.comwrote:
On Feb 15, 5:21 pm, Paul Rubin <http://phr...@NOSPAM.invalidwrote:
How can there be a structure datatype with an unpredictable
number of members?

It might have come across as a different question-sorry for any
confusion.

This may be where the "tuple is like a struct" analogy isn't so good,
and "tuple is like a list but immutable" is better.

In both of your examples, the caller of f() sent a fixed list of
arguments: (1,2,3,4,5,6,7) in the first case and (8,9,10) in the
second. Internally I bet the compiler wants to clean up that same
list of those same args when f() is finished.

Just as a thought experiment, do this for yourself. Implement f as:

def f(*args):
args = list(args)
print args

Now what is it you want to do with args that you can't do with it as a
tuple? Do you want some form of communication back to the caller to
occur, for example? Maybe some kind of pass-by-ref instead of pass-by-
value?
I wrote code that did exactly this just yesterday. I needed a list
because I wanted to pop arguments off as I consumed them.
Feb 17 '07 #38
"Paul McGuire" <pt***@austin.rr.comwrites:
This may be where the "tuple is like a struct" analogy isn't so good,
and "tuple is like a list but immutable" is better.
Right, that's what I'm getting at.
Feb 17 '07 #39
Quoth Paul Rubin <http://ph****@NOSPAM.invalid>:
| Donn Cave <do**@u.washington.eduwrites:
| What this proves is that you can implement
| an argument list at run time, but it by no means changes the
| nature of the argument list as a sequence.
|
| Right, it's treated as a sequence rather than a record structure.
| So is that consistent with the "tuples are record structures" view,
| as opposed to the "tuples are immutable lists" view?

A struct is a sequence, and your stdargs example is a pretty good case
in point.

When I said the function implemented with stdarg (...) support needs
information about its parameters to simulate a normal function, that
applies not only to the order of parameters but also their type.
Because -- as with structs, but unlike arrays -- the parameter list
has variable alignment to accommodate different sized types. So the
C parameter list really has every property of a struct -- naturally
contains mixed types, has variable alignment, normally accessed by name --
but it does have a defined order, and stdarg is a gimmick that uses it.

Order IS the struct property that you get from a tuple, so it is of
course important that the tuple is a sequence. The point is not whether
it's a sequence or not, but what kind of order it represents.

What I'm saying with the evidently overly abstract discussion in previous
posts, is that in a struct-like application, a tuple's order is of a
different nature than a list. Because in such application, that order
is absolute and in a sense atomic. Like a struct. Like an argument list.
That's why tuple has different applications than list, that's why it lacks
some of the sequential access features that lists have.

This must be more obvious in other languages that have a tuple type.
None that I know of support so many list or array sequence operations
on tuples, and in at least some the struct/record type is implemented
by adding names to a tuple but can still be treated as one (like Python's
mtime and stat types.)

Donn Cave, do**@drizzle.com
Feb 17 '07 #40
Neil Cerutti <ho*****@yahoo.comwrote:
On 2007-02-14, Farshid Lashkari <no@spam.comwrote:
Szabolcs Nagy wrote:
>>>L=[1]
L.extend((1,))
L
[1, 1]
Are list.extend() and list concatenation supposed to behave
differently? I always thought concatenation was just shorthand
for calling extend().

They are different. list.extend() mutates the list, returning
None, while the + operator returns a new, concatenated list.

+= on the other hand works very similarly to list.extend().
It does make an inconsistency though...
>>L=[1]
L+=(1,)
L
[1, 1]

Wheras
>>L=[1]
L=L+(1,)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can only concatenate list (not "tuple") to list
>>>
Ie

x += a

does not equal

x = x + a

which it really should for all types of x and a

(That is the kind of statement about which I'm sure someone will post
a perfectly reasonable counterexample ;-)

--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Feb 20 '07 #41
"Nick Craig-Wood" <ni**@craig-wood.comwrote:
>
Ie

x += a

does not equal

x = x + a

which it really should for all types of x and a
One would hope so , yes.

However, I think that the first form is supposed to update in place,
while the second is free to bind a new thing to x
>
(That is the kind of statement about which I'm sure someone will post
a perfectly reasonable counterexample ;-)
I don't think its reasonable - its just an accident of implementation..

- Hendrik

Feb 21 '07 #42
On 2007-02-21, Hendrik van Rooyen <ma**@microcorp.co.zawrote:
"Nick Craig-Wood" <ni**@craig-wood.comwrote:
>Ie

x += a

does not equal

x = x + a

which it really should for all types of x and a

One would hope so , yes.

However, I think that the first form is supposed to update in place,
while the second is free to bind a new thing to x
>(That is the kind of statement about which I'm sure someone
will post a perfectly reasonable counterexample ;-)

I don't think its reasonable - its just an accident of implementation..
Yup. It's analogous to the way you can do hill-starts with a
manual transmission, but not with an automatic transmission.

--
Neil Cerutti
Feb 21 '07 #43
Hendrik van Rooyen wrote:
I don't think its reasonable - its just an accident of implementation.
There's nothing accidental about the implementation of
the in-place operators. It was designed the way it is
so that it would work in a reasonable way with both
mutable and immutable objects.

--
Greg
Feb 22 '07 #44

This discussion thread is closed

Replies have been disabled for this discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.