simultaneous assignment

M

Mel Wilson

Roger said:
Steve R. Hastings wrote:




Is this guaranteed by the Python specification, or is it an artifact of
the current implementation?

AFAIK it's an artifact. The performance hit it Python
stopped sharing small integers could be enormous,
nonetheless sharing isn't part of the specification
My understanding has been that an
implementation is free to share integer objects or not, so using 'is'
as an equality test takes you into undefined territory, regardless of
the size of the value.
I agree. "is" is for working with linked-lists or trees, or
other applications where object identity is really and truly
what you're interested in.

Some amusing is/== facts, some suggested by recent threads

Python 2.4.2 (#1, Jan 23 2006, 21:24:54)
[GCC 3.3.4] on linux2
Type "help", "copyright", "credits" or "license" for more
information.False
 
S

Steve R. Hastings

of course they do - ie isinstance(False,int) is True and False == 0

I stand corrected. I tested most of my examples; I thought I had tested
that example, but clearly I did not.

I just tried "0 == False" in Python and it does evaluate True.

"[] == False" still does not, of course...

Thank you for the correction.
 
S

Steve R. Hastings

Is this guaranteed by the Python specification, or is it an artifact of
the current implementation?

I believe it's an artifact of the current implementation. And I only
tested that on CPython; I don't know if it will work like that on
Jython, IronPython, etc. I can't imagine why the Python spec would
guarantee such a thing anyway. :)

My understanding has been that an
implementation is free to share integer objects or not, so using 'is'
as an equality test takes you into undefined territory, regardless of
the size of the value.

This sounds correct to me. (Note: I do not claim to be an authority on
Python! But there are several authorities here who will no doubt correct
this if I am wrong.)
 
S

Steve R. Hastings

note that generators have no defined length - precisely because they feed
values one at a time while you need them all together to speak of a
length. The second expression will raise a TypeError because of that.

Er, yes. If I had actually run that code, I would have seen that error.

Thank you for the correction.

If you want to count objects
with a generator expression, use

sum(1 for v in seq if some_condition(v))

which is also clearer imho; summing ones for each item satisfying a
condition - isn't that a definition of counting ?

That is indeed very clear and I like it.

You could also use a function that counts all different values in a list,
reducing the list to a dictionary whose keys are the unique values from
the list. I got the idea from a discussion here on comp.lang.python; I
called my version of it tally().

d = tally(bool(x) for x in seq)
print d[True] # prints how many true values in seq
print d[False] # prints how many false values in seq


tally() is in my iterwrap.py module, which you can get here:

http://home.blarg.net/~steveha/iterwrap.tar.gz
 
B

bruno at modulix

John said:
Actually, I kind of thought that maybe it *didn't* matter in this
particular example anyway, so my question was meant to be more general
than I might have written it. It seems like the identity issue can be a
problem in certain cases, although I can't think of a case right now! :)

something
a = b = []
a.append(1)
print b
 
C

Christos Georgiou

Another thing I'm trying to do is write a function that tests to see if
a list contains exactly one true item, and the rest are false (obviously
this would have to be a list of boolean values, I guess). I'm sure this
isn't a handy utility, but I enjoy figuring out how to implement it.
return count == sum(map(bool, predicates))
true_count_is([True, True, False], 1) False
true_count_is([True, False, False], 1)
True
 
J

John Salerno

bruno said:
John said:
Actually, I kind of thought that maybe it *didn't* matter in this
particular example anyway, so my question was meant to be more general
than I might have written it. It seems like the identity issue can be a
problem in certain cases, although I can't think of a case right now! :)

something
a = b = []
a.append(1)
print b

Ah ha!
 
E

Edward Elliott

Steve said:
You could also use a function that counts all different values in a list,
reducing the list to a dictionary whose keys are the unique values from
the list.

Wouldn't reducing to a set instead of a dict make more sense if all you want
to do is count uniq elements?
 
S

Steve R. Hastings

Wouldn't reducing to a set instead of a dict make more sense if all you want
to do is count uniq elements?

My apologies for not explaining tally() better.

The dict has one key for each unique element, and the value associated
with each key is a count of how many times that element appeared in the
original list.

lst = ['a', 'b', 'b', 'c', 'c', 'c']
d = iterwrap.tally(lst)
print d # prints something like: {'a': 1, 'c': 3, 'b': 2}


If you didn't care how many times the values appeared in the original
list, and just just wanted the unique values, then a set would be perfect.

If you happen to have tally(), it is an easy way to solve the original
problem: figure out whether a list has exactly one true value in it.

d = tally(bool(x) for x in lst)
if d[True] == 1:
print "and there was much rejoicing"
 
P

Paul Rubin

Dave Hansen said:
Well, if you want something minimalist, you could try

def truth_test(seq):
return sum(1 for item in seq if item) == 1

def truth_test(seq):
return sum(map(bool, seq)) == 1
 
B

Boris Borcic

Steve said:
You could also use a function that counts all different values in a list,
reducing the list to a dictionary whose keys are the unique values from
the list. I got the idea from a discussion here on comp.lang.python; I
called my version of it tally().

d = tally(bool(x) for x in seq)
print d[True] # prints how many true values in seq
print d[False] # prints how many false values in seq


tally() is in my iterwrap.py module, which you can get here:

http://home.blarg.net/~steveha/iterwrap.tar.gz
{'a': 3, 'c': 3, 'b': 4}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,278
Latest member
BuzzDefenderpro

Latest Threads

Top