FAQ
A new python convert is now looking for a replacement for another perl idiom.

In particular, since Perl is weakly typed, I used to be able to use
unpack to unpack sequences from a string, that I could then use
immediately as integers.

In python, I find that when I use struct.unpack I tend to get strings.
(Maybe I am using it wrong?)

def f(x,y,z): print x+y+z;

f( *struct.unpack('2s2s2s','123456'))
123456

(the plus concatenates the strings returned by unpack)

But what I want is:

f( *map(lambda x: int(x), struct.unpack('2s2s2s','123456')))
102

But this seems too complicated.

I see two resolutions:

1. There is a way using unpack to get out string-formatted ints?

2. There is something like map(lambda x: int(x).... without all the
lambda function call overhead. (e.g., cast tuple)?
[And yes: I know I can write my own "cast_tuple" function -- that's
not my point. My point is that I want a super-native python inline
solution like (hopefully shorter than) my "map" version above. I
don't like defining trivial functions.]

W

Search Discussions

  • Nick Raptis at Jul 28, 2010 at 1:27 pm

    On 07/28/2010 04:15 PM, wheres pythonmonks wrote:
    f( *map(lambda x: int(x), struct.unpack('2s2s2s','123456')))
    102

    But this seems too complicated.

    Well, you don't need the lambda at all
    int === lambda x: int(x)

    So just write

    It's like writing:
    def myint(x):
    return int(x)


    Nick,

    Warm thanks to Steven D' Aprano who taught me that just yesterday in the
    Tutor list ;)
  • Nick Raptis at Jul 28, 2010 at 1:31 pm
    Ep, that missing line should be:
    On 07/28/2010 04:27 PM, Nick Raptis wrote:
    On 07/28/2010 04:15 PM, wheres pythonmonks wrote:

    f( *map(lambda x: int(x), struct.unpack('2s2s2s','123456')))
    102

    But this seems too complicated.
    Well, you don't need the lambda at all
    int === lambda x: int(x)

    So just write
    f( *map(int, struct.unpack('2s2s2s', '123456')))

    Pretty compact now, isn't it?
    It's like writing:
    def myint(x):
    return int(x)


    Nick,

    Warm thanks to Steven D' Aprano who taught me that just yesterday in
    the Tutor list ;)
  • Wheres pythonmonks at Jul 28, 2010 at 1:35 pm
    Thanks ... I thought int was a type-cast (like in C++) so I assumed I
    couldn't reference it.


    On Wed, Jul 28, 2010 at 9:31 AM, Nick Raptis wrote:
    Ep, that missing line should be:
    On 07/28/2010 04:27 PM, Nick Raptis wrote:
    On 07/28/2010 04:15 PM, wheres pythonmonks wrote:

    f( *map(lambda x: int(x), struct.unpack('2s2s2s','123456')))
    102

    But this seems too complicated.
    Well, you don't need the lambda at all
    int ? === ? ?lambda x: int(x)

    So just write
    f( *map(int, struct.unpack('2s2s2s', '123456')))

    Pretty compact now, isn't it?
    It's like writing:
    def myint(x):
    ? ?return int(x)


    Nick,

    Warm thanks to Steven D' Aprano who taught me that just yesterday in the
    Tutor list ;)
    --
    http://mail.python.org/mailman/listinfo/python-list
  • Ulrich Eckhardt at Jul 28, 2010 at 1:58 pm

    wheres pythonmonks wrote:
    Thanks ... I thought int was a type-cast (like in C++) so I assumed I
    couldn't reference it.
    Hopefully somebody correct me if I explain this badly, but I'll take a
    shot...


    Firstly, "int" is a class. Python doesn't make a distinction between builtin
    types and class types like C++, where you e.g. can't derive from builtin
    types.

    Secondly, the class is callable like a function. When called, it creates an
    instance of that class. Therefore, when you create an object it has a
    similar syntax as when calling a function.

    Lastly, classes are not special. Like any variable or function they can be
    referenced by a name or by multiple names, and thus be passed as parameters
    to a function.

    Cheers!

    Uli

    --
    Sator Laser GmbH
    Gesch?ftsf?hrer: Thorsten F?cking, Amtsgericht Hamburg HR B62 932
  • Lie Ryan at Aug 5, 2010 at 10:27 am

    On Wed, 28 Jul 2010 15:58:29 +0200, Ulrich Eckhardt wrote:
    wheres pythonmonks wrote:
    Thanks ... I thought int was a type-cast (like in C++) so I
    assumed I
    couldn't reference it.
    Firstly, "int" is a class. Python doesn't make a distinction
    between builtin
    types and class types like C++, where you e.g. can't derive from builtin
    types.
    That wasn't true until recently with class and type unification. In
    some older versions of python you cannot derive from build in types
    either.
  • Bruno Desthuilliers at Jul 28, 2010 at 2:11 pm

    wheres pythonmonks a ?crit :
    Thanks ... I thought int was a type-cast (like in C++) so I assumed I
    couldn't reference it.
    Python has no C/C++ like "type-cast". "int" is the builtin integer type,
    and instanciating an object in Python is done by calling it's type.
    Remember that in Python, everything (at least everything you can bind to
    a name) is an object (including functions, types etc), and that
    functions are just one kind of callable objects (types - aka "classes"
    -, methods and a few other builtin objects are callable too, and you can
    of course define your own callable type).

    HTH
  • Steven D'Aprano at Jul 28, 2010 at 2:32 pm

    On Wed, 28 Jul 2010 09:35:52 -0400, wheres pythonmonks wrote:

    Thanks ... I thought int was a type-cast (like in C++) so I assumed I
    couldn't reference it.
    Python doesn't have type-casts in the sense of "tell the compiler to
    treat object of type A as type B instead". The closest Python has to that
    is that if you have an instance of class A, you can do this:

    a = A() # make an instance of class A
    a.__class__ = B # tell it that it's now class B

    and hope that it won't explode when you try to use it :/

    I make that seem like a dangerous thing to do, but it's not really. There
    actually are sensible use-cases for such a thing, you can't do it to
    built-ins (which would be dangerous!), and the worst that will happen
    with classes written in Python is they'll raise an exception when you try
    calling a method, rather than dump core.

    Otherwise, all type conversions in Python create a new instance of the
    new type, and the conversion functions themselves (int, str, etc.) are
    actual type objects which you can pass around to functions:
    type(int)
    <type 'type'>

    Calling int(x) calls the int constructor with argument x, and returns a
    new int object. (In the *specific* case of int, it will sometimes cache
    small integers and re-use the same one multiple times, but don't count on
    that behaviour since it's an implementation-specific optimization.)


    --
    Steven
  • Carl Banks at Jul 28, 2010 at 3:47 pm

    On Jul 28, 7:32?am, Steven D'Aprano <st... at REMOVE-THIS- cybersource.com.au> wrote:
    On Wed, 28 Jul 2010 09:35:52 -0400, wheres pythonmonks wrote:
    Thanks ... I thought int was a type-cast (like in C++) so I assumed I
    couldn't reference it.
    Python doesn't have type-casts in the sense of "tell the compiler to
    treat object of type A as type B instead". The closest Python has to that
    is that if you have an instance of class A, you can do this:

    a = A() ?# make an instance of class A
    a.__class__ = B ?# tell it that it's now class B

    and hope that it won't explode when you try to use it :/
    Type casts in C and non-pathlogical C++ don't modify the object they
    are casting.

    int (and str, float, etc.) is the closest thing to a type cast in
    Python.


    Carl Banks
  • Steven D'Aprano at Jul 29, 2010 at 2:45 am

    On Wed, 28 Jul 2010 08:47:52 -0700, Carl Banks wrote:

    On Jul 28, 7:32?am, Steven D'Aprano <st... at REMOVE-THIS-
    cybersource.com.au> wrote:
    On Wed, 28 Jul 2010 09:35:52 -0400, wheres pythonmonks wrote:
    Thanks ... I thought int was a type-cast (like in C++) so I assumed I
    couldn't reference it.
    Python doesn't have type-casts in the sense of "tell the compiler to
    treat object of type A as type B instead". The closest Python has to
    that is that if you have an instance of class A, you can do this:

    a = A() ?# make an instance of class A a.__class__ = B ?# tell it that
    it's now class B

    and hope that it won't explode when you try to use it :/
    Type casts in C and non-pathlogical C++ don't modify the object they are
    casting.

    int (and str, float, etc.) is the closest thing to a type cast in
    Python.

    Perhaps I have been misinformed, but my understanding of C type-casts is
    that (where possible), a cast like `int(var)` merely tells the compiler
    to temporarily disregard the type of var and treat it as if it were an
    int. In other words, it's a compiler instruction rather than a conversion
    function.



    --
    Steven
  • Ulrich Eckhardt at Jul 29, 2010 at 7:21 am

    Steven D'Aprano wrote:
    Perhaps I have been misinformed, but my understanding of C type-casts is
    that (where possible), a cast like `int(var)` merely tells the compiler
    to temporarily disregard the type of var and treat it as if it were an
    int. In other words, it's a compiler instruction rather than a conversion
    function.
    You are misinformed. The result of a cast in C or C++ behaves as if a
    temporary was created:

    int x = 0;
    unsigned(x)--; // invalid, compiler error

    Now, where this distinction gets blurred is when you are casting pointers:

    (*(unsigned*)&x)--;

    or, in C++, references:

    reinterpret_cast<unsigned&>(x)--;

    Technically, these are still invalid though, only that they give you
    undefined behaviour at runtime instead of a compiler error, but those are
    already very fine details of the according standards.


    Uli

    --
    Sator Laser GmbH
    Gesch?ftsf?hrer: Thorsten F?cking, Amtsgericht Hamburg HR B62 932
  • Steven D'Aprano at Jul 29, 2010 at 8:28 am

    On Thu, 29 Jul 2010 09:21:37 +0200, Ulrich Eckhardt wrote:

    Steven D'Aprano wrote:
    Perhaps I have been misinformed, but my understanding of C type-casts
    is that (where possible), a cast like `int(var)` merely tells the
    compiler to temporarily disregard the type of var and treat it as if it
    were an int. In other words, it's a compiler instruction rather than a
    conversion function.
    You are misinformed. The result of a cast in C or C++ behaves as if a
    temporary was created:
    Fair enough. Thank you.




    --
    Steven
  • Albert van der Horst at Aug 7, 2010 at 1:54 pm
    In article <1pm7i7-473.ln1 at satorlaser.homedns.org>,
    Ulrich Eckhardt wrote:
    Steven D'Aprano wrote:
    Perhaps I have been misinformed, but my understanding of C type-casts is
    that (where possible), a cast like `int(var)` merely tells the compiler
    to temporarily disregard the type of var and treat it as if it were an
    int. In other words, it's a compiler instruction rather than a conversion
    function.
    You are misinformed. The result of a cast in C or C++ behaves as if a
    temporary was created:

    int x = 0;
    unsigned(x)--; // invalid, compiler error

    Now, where this distinction gets blurred is when you are casting pointers:

    (*(unsigned*)&x)--;

    or, in C++, references:

    reinterpret_cast<unsigned&>(x)--;

    Technically, these are still invalid though, only that they give you
    undefined behaviour at runtime instead of a compiler error, but those are
    already very fine details of the according standards.
    There is just one conclusion that should remain from this.
    If you're ever going to program in in c or c++, casts are to be
    avoided like the plague. (And recently they have been thought over in
    C++ to be split in different names with the reinterpret_cast the most
    dangerous, but at least it is a big read flag.)
    I see an analogy with goto's in my experience. Once you understand
    how bad they are, you discover there is always a better solution.

    It is unfortunate that cast's in Python share the same name, but
    it is kind of unavoidable because it is about the proper CS name to use.
    Uli
    Groetjes Albert

    --
    --
    Albert van der Horst, UTRECHT,THE NETHERLANDS
    Economic growth -- being exponential -- ultimately falters.
    albert at spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
  • Carl Banks at Aug 7, 2010 at 8:02 pm

    On Aug 7, 6:54?am, Albert van der Horst wrote:
    In article <1pm7i7-473.... at satorlaser.homedns.org>,
    Ulrich Eckhardt ?wrote:


    Steven D'Aprano wrote:
    Perhaps I have been misinformed, but my understanding of C type-casts is
    that (where possible), a cast like `int(var)` merely tells the compiler
    to temporarily disregard the type of var and treat it as if it were an
    int. In other words, it's a compiler instruction rather than a conversion
    function.
    You are misinformed. The result of a cast in C or C++ behaves as if a
    temporary was created:
    ?int x = 0;
    ?unsigned(x)--; // invalid, compiler error
    Now, where this distinction gets blurred is when you are casting pointers:
    ?(*(unsigned*)&x)--;
    or, in C++, references:
    ?reinterpret_cast<unsigned&>(x)--;
    Technically, these are still invalid though, only that they give you
    undefined behaviour at runtime instead of a compiler error, but those are
    already very fine details of the according standards.
    There is just one conclusion that should remain from this.
    If you're ever going to program in in c or c++, casts are to be
    avoided like the plague.
    You sound as if you don't usually program in C or C++, which suggests
    to me that you shouldn't be offering advice on how to program in these
    languages. I program in C all the time, and I can tell you you can't
    get very far in C or C++ without sometimes resorting to type-casts. (C
    ++ offers more help for class types, but there's not a lot you can do
    to avoid casts for converting between built-in types.)

    The CPython interpreter uses type casts all over the place, BTW.
    (And recently they have been thought over in
    C++ to be split in different names with the reinterpret_cast the most
    dangerous, but at least it is a big read flag.)
    If by "recently" you mean "10 years ago", and by "thought over" you
    mean "standardized and implemented".
    I see an analogy with goto's in my experience. Once you understand
    how bad they are, you discover there is always a better solution.
    What better solution do you propose for this that doesn't use type-
    casting?

    int a, b;
    double ratio;

    ratio = (double)a/b;

    It is unfortunate that cast's in Python share the same name, but
    it is kind of unavoidable because it is about the proper CS name to use.
    Not really. Very few people call int(), float(), and company "type
    casts". They aren't type casts at all, they are constructors that
    sometimes have the same semantics as type casts in C.


    Carl Banks
  • Carl Banks at Aug 8, 2010 at 4:34 am

    On Aug 7, 8:18?pm, Dennis Lee Bieber wrote:
    On Sat, 7 Aug 2010 13:02:56 -0700 (PDT), Carl Banks
    <pavlovevide... at gmail.com> declaimed the following in
    gmane.comp.python.general:


    Not really. ?Very few people call int(), float(), and company "type
    casts". ?They aren't type casts at all, they are constructors that
    sometimes have the same semantics as type casts in C.
    ? ? ? ? Given the different syntax, I never see them as "type casts"... They
    look like functions that take an argument (or more than one:
    int("FE", 16) ) and convert it into a value of the type named...

    ? ? ? ? C, OTOH, I'm never sure if a conversion (the bit pattern of the
    result is different from the bit pattern of the source) or an
    equivalencing (the bit pattern of the result is the same as the bit
    pattern of the source, but the /interpretation/ of those bits is
    different) is taking place.
    C's type casts are always a conversion. There are no exceptions I'm
    aware of.


    The only way to reinterpret bits in C is to take a reference, cast the
    pointer, and then derefernece again. (C++ has a reinterpret_cast for
    that.)

    *(int*)&x


    Casting an integer to a pointer retains the same bits because a
    pointer's "value" is considered to be the same as the unsigned integer
    with the same bit pattern.

    Pointer-to-pointer casts in C++ don't always retain the same bits,
    BTW.


    Carl Banks
  • Carl Banks at Jul 29, 2010 at 3:29 pm

    On Jul 28, 7:45?pm, Steven D'Aprano <steve-REMOVE- T... at cybersource.com.au> wrote:
    On Wed, 28 Jul 2010 08:47:52 -0700, Carl Banks wrote:
    On Jul 28, 7:32?am, Steven D'Aprano <st... at REMOVE-THIS-
    cybersource.com.au> wrote:
    On Wed, 28 Jul 2010 09:35:52 -0400, wheres pythonmonks wrote:
    Thanks ... I thought int was a type-cast (like in C++) so I assumed I
    couldn't reference it.
    Python doesn't have type-casts in the sense of "tell the compiler to
    treat object of type A as type B instead". The closest Python has to
    that is that if you have an instance of class A, you can do this:
    a = A() ?# make an instance of class A a.__class__ = B ?# tell it that
    it's now class B
    and hope that it won't explode when you try to use it :/
    Type casts in C and non-pathlogical C++ don't modify the object they are
    casting.
    int (and str, float, etc.) is the closest thing to a type cast in
    Python.
    Perhaps I have been misinformed, but my understanding of C type-casts is
    that (where possible), a cast like `int(var)`
    (int)var

    merely tells the compiler
    to temporarily disregard the type of var and treat it as if it were an
    int. In other words, it's a compiler instruction rather than a conversion
    function.
    Even if it did, it would still be temporary. The type of the variable
    remains unchanged.

    But it doesn't disregard the original type: type casts try to preserve
    semantic value. (double)1 returns 1.0, which is not only a different
    bit pattern but a different size. That's exactly what float() does in
    Python.


    Carl Banks
  • John Nagle at Jul 29, 2010 at 5:45 am

    On 7/28/2010 7:32 AM, Steven D'Aprano wrote:
    On Wed, 28 Jul 2010 09:35:52 -0400, wheres pythonmonks wrote:

    Thanks ... I thought int was a type-cast (like in C++) so I assumed I
    couldn't reference it.
    Python doesn't have type-casts in the sense of "tell the compiler to
    treat object of type A as type B instead". The closest Python has to that
    is that if you have an instance of class A, you can do this:

    a = A() # make an instance of class A
    a.__class__ = B # tell it that it's now class B

    and hope that it won't explode when you try to use it :/

    I make that seem like a dangerous thing to do, but it's not really. There
    actually are sensible use-cases for such a thing, you can't do it to
    built-ins (which would be dangerous!), and the worst that will happen
    with classes written in Python is they'll raise an exception when you try
    calling a method, rather than dump core.
    The main use for that sort of thing is in constructing objects
    without their cooperation. "copy" and "pickle" do that,
    as they build up objects without running their initializers.

    Arguably, that would be better done with a built-in function for
    creating arbitrary objects. Something like:

    x = new_object("classname",
    (("attr1", val1), ("attr2", val2)))

    to create a new object in one atomic operation.
    Storing into "__class__" may not be portable across
    Python implementations. The implications for multiple
    inheritance are difficult. It's really a hack for CPython.

    John Nagle
  • Steven D'Aprano at Jul 29, 2010 at 6:24 am
    On Wed, 28 Jul 2010 22:45:19 -0700, John Nagle wrote:

    [...]
    if you have an instance of class A, you can do this:

    a = A() # make an instance of class A
    a.__class__ = B # tell it that it's now class B

    and hope that it won't explode when you try to use it :/
    [...]
    The main use for that sort of thing is in constructing objects
    without their cooperation. "copy" and "pickle" do that, as they build
    up objects without running their initializers.
    True, but there are other use-cases as well, such as the recipe for ring
    buffer which made it into the Python Cookbook. I think this is it:

    http://code.activestate.com/recipes/68429-ring-buffer/

    Storing into "__class__"
    may not be portable across Python implementations. The implications for
    multiple inheritance are difficult. It's really a hack for CPython.
    I believe that it is intended as a language feature, not an
    implementation-specific hack:

    http://bytes.com/topic/python/answers/449635-assigning-self-__class__


    While it's an advanced technique that isn't terribly common, I don't see
    any reason to avoid it.


    --
    Steven
  • Duncan Booth at Jul 28, 2010 at 1:31 pm

    wheres pythonmonks wrote:

    2. There is something like map(lambda x: int(x).... without all the
    lambda function call overhead. (e.g., cast tuple)?
    Yes there is: "lambda x: int(x)" is just a roundabout way of writing "int"
  • Hexamorph at Jul 28, 2010 at 1:47 pm

    wheres pythonmonks wrote:
    A new python convert is now looking for a replacement for another perl idiom.

    In particular, since Perl is weakly typed, I used to be able to use
    unpack to unpack sequences from a string, that I could then use
    immediately as integers.

    In python, I find that when I use struct.unpack I tend to get strings.
    (Maybe I am using it wrong?)

    def f(x,y,z): print x+y+z;

    f( *struct.unpack('2s2s2s','123456'))
    123456

    (the plus concatenates the strings returned by unpack)

    But what I want is:

    f( *map(lambda x: int(x), struct.unpack('2s2s2s','123456')))
    102

    But this seems too complicated.

    I see two resolutions:

    1. There is a way using unpack to get out string-formatted ints?

    2. There is something like map(lambda x: int(x).... without all the
    lambda function call overhead. (e.g., cast tuple)?
    [And yes: I know I can write my own "cast_tuple" function -- that's
    not my point. My point is that I want a super-native python inline
    solution like (hopefully shorter than) my "map" version above. I
    don't like defining trivial functions.]

    W
    In [31]: import re

    In [32]: sum(int(x) for x in re.findall("..", s))
    Out[32]: 102

    To get a tuple instead of the sum, just do:

    In [33]: tuple(int(x) for x in re.findall("..", s))
    Out[33]: (12, 34, 56)
  • Tim Chase at Jul 28, 2010 at 2:14 pm

    On 07/28/10 08:15, wheres pythonmonks wrote:
    f( *map(lambda x: int(x), struct.unpack('2s2s2s','123456')))
    102

    1. There is a way using unpack to get out string-formatted ints?
    well, you can use
    s = '123456'
    [int(s[i:i+2]) for i in range(0, len(s), 2)]
    [12, 34, 56]
    f(*_)
    102

    While your "f()" is just a boring placeholder I assume, you could
    also write that as

    sum(int(s[i:i+2]) for i in range(0, len(s), 2))

    and skip creating f() altogether if all it does is add its arguments.

    -tkc
  • Lie Ryan at Aug 5, 2010 at 10:39 am

    On Wed, 28 Jul 2010 09:15:24 -0400, wheres pythonmonks wrote:
    A new python convert is now looking for a replacement for another
    perl idiom.

    A functional alternative:
    l = ...
    seqint = compose(map, int)
    print f(seqint(l))

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedJul 28, '10 at 1:15p
activeAug 8, '10 at 4:34a
posts22
users13
websitepython.org

People

Translate

site design / logo © 2022 Grokbase