2

私は毎日 Ruby を使用していますが、Python に問題があります。この言語は非常に似ていることがわかりました...しかし、Rubyからの移行にはいくつか問題があります:)

このアクションをPythonで変換するのを手伝ってください:

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

これにより、文字列からアンパックされた値を持つ 3 つの変数が返されます。

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

Pythonでそれを表現するのを手伝ってくださいありがとう!

4

5 に答える 5

9
s = "qwerty2012"
(a, b, c) = s[:1], s[1:5], s[5:]
于 2012-06-18T23:25:46.663 に答える
5

Python にはstructという名前の同様のモジュールがあります。Ruby や PHP が Perl から持ち出したのと同じ方法で、残りの文字列を取得する機能が欠けています。あなたはほとんどそこに着くことができます:

>>> 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']

structモジュールが Perl の残りの部分を実装したunpackことを望みますpack。それらはバイナリ パケットを分解するのに非常に便利な関数でしたが、残念ながら。

于 2012-06-19T00:13:29.340 に答える
4
s = "qwerty2012"
var, some_var, another_var = s[:1], s[1:5], s[5:]

それぞれ代入と利回りを行います:

q
wert
y2012

上記の割り当てでは、 Python Docsで説明されているスライス表記を使用しています。This SO post Good Primer for Python Slice Notationも良い説明を提供します。

于 2012-06-18T23:26:14.773 に答える
2

の予備的な再現は次の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+|\*|)')

それはあなたの与えられた例でうまくいきます、

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

しかし、まだ実装されていないデータ型の長いリストがあります (ドキュメントを参照してください)。

于 2012-06-19T01:22:07.080 に答える
1

これにより、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)

出力:

('q', 'wert', 'y2012')
于 2012-06-19T04:50:23.607 に答える