2

I am working with Ruby every day, but i have an issue in Python. I was found this languages very similar... But I have some problems with migration from Ruby :)

Please, help me to convert this action in python:

 string = "qwerty2012" (var, some_var, another_var) = string.unpack("a1a4a*") 

this should return three variables with unpacked values from string:

 var = "q" # a1 some_var = "wert" # a4 another_var = "y2012" # a* 

Help me to represent it in Python Thank you!

6
  • 3
    You probably don't want to name a variable string Commented Jun 18, 2012 at 23:26
  • 1
    Actually, string is fine. The type in Python is str. Commented Jun 18, 2012 at 23:28
  • 2
    @ChinmayKanchi, yeah, but there's also the string module, and we don't know if OP is importing it, so assigning string to something new would take it out of the namespace. Kind of bad practice. Commented Jun 18, 2012 at 23:29
  • 1
    @Chinmay But there's still the string package - but yes it's probably not especially problematic. Commented Jun 18, 2012 at 23:29
  • For some reason, I thought the module was called strings. Guess that says something about how often I find myself using it. Yeah, not a great idea to name something the same as a standard module. Commented Jun 18, 2012 at 23:32

5 Answers 5

9
s = "qwerty2012" (a, b, c) = s[:1], s[1:5], s[5:] 
Sign up to request clarification or add additional context in comments.

1 Comment

Levon, sorry for it. You are be the first! Thank you!
5

Python does have a similar module named struct. It lacks the ability to grab the rest of the string in the same way that Ruby and PHP lifted from Perl. You can almost get there though:

>>> import struct >>> s = 'qwerty2012' >>> struct.unpack_from('1s4s', s) ('q', 'wert') >>> def my_unpack(format, packed_string): ... result = [] ... result.extend(struct.unpack_from(format, packed_string)) ... chars_gobbled = struct.calcsize(format) ... rest = packed_string[chars_gobbled:] ... if rest: ... result.append(rest) ... return result ... >>> my_unpack('1s4s', 'qwerty2012') ['q', 'wert', 'y2012'] >>> my_unpack('1s4s', 'qwert') ['q', 'wert'] >>> [hex(x) for x in my_unpack('<I', '\xDE\xAD\xBE\xEF')] ['0xefbeadde'] 

I wish that the struct module implemented the rest of Perl's unpack and pack since they were incredibly useful functions for ripping apart binary packets but alas.

Comments

4
s = "qwerty2012" var, some_var, another_var = s[:1], s[1:5], s[5:] 

will do the assignment and yield respectively:

q wert y2012 

The above assignment makes use of slice notation as described by the Python Docs. This SO post Good Primer for Python Slice Notation gives a good explanation too.

Comments

2

Here's a preliminary recreation of unpack:

import re import StringIO def unpack(s, fmt): fs = StringIO.StringIO(s) res = [] for do,num in unpack.pattern.findall(fmt): if num == '*': num = len(s) elif num == '': num = 1 else: num = int(num) this = unpack.types[do](num, fs) if this is not None: res.append(this) return res unpack.types = { '@': lambda n,s: s.seek(n), # skip to offset 'a': lambda n,s: s.read(n), # string 'A': lambda n,s: s.read(n).rstrip(), # string, right-trimmed 'b': lambda n,s: bin(reduce(lambda x,y:256*x+ord(y), s.read(n), 0))[2:].zfill(8*n)[::-1], # binary, LSB first 'B': lambda n,s: bin(reduce(lambda x,y:256*x+ord(y), s.read(n), 0))[2:].zfill(8*n) # binary, MSB first } unpack.pattern = re.compile(r'([a-zA-Z@](?:_|!|<|>|!<|!>|0|))(\d+|\*|)') 

It works for your given example,

unpack("qwerty2012", "a1a4a*") # -> ['q', 'wert', 'y2012'] 

but has a long list of datatypes not yet implemented (see the documentation).

Comments

1

This might ease your migration from Ruby:

import re import struct def unpack(format, a_string): pattern = r'''a(\*|\d+)\s*''' widths = [int(w) if w is not '*' else 0 for w in re.findall(pattern, format)] if not widths[-1]: widths[-1] = len(a_string) - sum(widths) fmt = ''.join('%ds' % f for f in widths) return struct.unpack_from(fmt, a_string) (var, some_var, another_var) = unpack('a1a4a*', 'qwerty2012') # also 'a1 a4 a*' OK print (var, some_var, another_var) 

Output:

('q', 'wert', 'y2012') 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.