كيفية تحويل إدخال ملف تسلسل Dumbo إلى TAB SPALED TEXT

StackOverflow https://stackoverflow.com/questions/1625757

  •  06-07-2019
  •  | 
  •  

سؤال

لدي مدخلات ، والتي يمكن أن تكون بدائية واحدة أو قائمة أو tuple من البدائية.

أرغب في تسطيحه إلى قائمة فقط ، مثل ذلك:

def flatten(values):
    return list(values)

ستكون الحالة العادية متسقة (SomeIterablethatis nostastring)

ولكن إذا كانت القيم = '1234' ، فسأحصل على ['1' ، '2' ، '3' ، '4'] ، لكنني أريد ['1234'

وإذا كان القيم = 1 ، فسأحصل على نوع typeerror: كائن "int" غير أمر لا يطاق ، لكنني أريد [1

هل هناك طريقة أنيقة للقيام بذلك؟ ما أريد فعله حقًا في النهاية هو مجرد "

تحرير: دعني أشرح هذا بشكل أفضل ...

أرغب في تحويل ملف تسلسل ثنائي Hadoop إلى ملف نصي منفصل عن علامة تبويب مسطحة باستخدام Dumbo. باستخدام خيار تنسيق الإخراج ، نص outputformat

Dumbo هو غلاف Python حول تدفق Hadoop. باختصار ، أحتاج إلى كتابة وظيفة Mapper:

Def Mapper (مفتاح ، قيم) #بعض الأشياء العائد K ، V

حيث K عبارة عن سلسلة من الجزء الأول في المفتاح ، والقيمة عبارة عن سلسلة مفصولة مفصولة تحتوي على بقية المفتاح والقيم كسلاسل.

على سبيل المثال:

input: (123, [1,2,3])
output: ('123', '1\t2\t\t3')

أو أكثر تعقيدًا:

input: ([123, 'abc'], [1,2,3])
output: ('123', 'abc\t1\t2\t\t3')

يمكن أن يكون مفتاح الإدخال أو القيمة بدائية أو قائمة/tuple من الدالة الأولية التي أرغب في وظيفة "Flatten" التي يمكن أن تتعامل مع أي شيء ، وإرجاع قائمة القيم.

للحصول على القيمة الخارجية ، سأفعل شيئًا مثل هذا v = ' t'..

هل كانت مفيدة؟

المحلول

يبدو أنك تريد itertools.chain(). ستحتاج إلى سلاسل خاصة ، لأنها في الحقيقة مجرد تكرار من الشخصيات.

تحديث:

هذه مشكلة أبسط بكثير إذا قمت بذلك كمولد متكرر. جرب هذا:

def flatten(*seq):
    for item in seq:
        if isinstance(item, basestring):
            yield item
        else:
            try:
                it = iter(item)
            except TypeError:
                yield item
                it = None
            if it is not None:
                for obj in flatten(it):
                    yield obj

هذا يعيد جهاز التكرار بدلاً من القائمة ، ولكن يتم تقييمه بتكاسل ، وهو ما تريده على أي حال. إذا كنت بحاجة حقًا إلى قائمة ، فما عليك سوى الاستخدام list(flatten(seq)) في حين أن.

تحديث 2:

كما أشار الآخرون ، إذا كان ما تريده حقًا هو تمرير هذا str.join(), ، ستحتاج إلى تحويل جميع العناصر إلى سلاسل. للقيام بذلك ، يمكنك إما استبدال yield foo مع yield str(foo) خلال المثال الخاص بي أعلاه ، أو استخدم رمزًا مثل ما يلي:

"\t".join(str(o) for o in flatten(seq))

نصائح أخرى

بناءً على سؤالك المتكرر ، هذا mapper قد تفعل الوظيفة ما تريد:

def mapper(key, values):
    r"""Specification: do some stuff yield k, v where k is a string from the
    first part in the key, and value is a tab separated string containing the
    rest of the key and the values as strings.

    >>> mapper(123, [1,2,3])
    ('123', '1\t2\t3')

    >>> mapper([123, 'abc'], [1,2,3])
    ('123', 'abc\t1\t2\t3')
    """
    if not isinstance(key, list):
        key = [key]
    k, v = key[0], key[1:]
    v.extend(values)
    return str(k), '\t'.join(map(str, v))

if __name__ == '__main__':
    import doctest
    doctest.testmod()

يبدو أنك ربما تريد تغيير ذلك return إلى yield. يفترض هذا أيضًا أن مفتاح الإدخال سيكون دائمًا عنصرًا واحدًا أو قائمة بالعناصر (وليس قائمة القوائم) وأن قيم الإدخال ستكون دائمًا قائمة بالعناصر (مرة أخرى ، وليس قائمة القوائم).

هل يلبي ذلك متطلباتك؟

يجب أن أقول إن المتطلبات المعلنة غريبة ، ولا أعتقد تسطح هو الاسم الصحيح لهذا النوع من العملية. ولكن إذا كنت كذلك حقًا تأكد من أن هذا ما تريده ، فهذا ما يمكنني التمييز عنه من سؤالك:

>>> import itertools 
>>> def to_list_of_strings(input):
...      if isinstance(input, basestring):   # In Py3k: isinstance(input, str)
...          return [input]
...      try:
...          return itertools.chain(*map(to_list_of_strings, input))
...      except TypeError:
...          return [str(input)]
... 
>>> '\t'.join(to_list_of_strings(8))
'8'
>>> '\t'.join(to_list_of_strings((1, 2)))
'1\t2'
>>> '\t'.join(to_list_of_strings("test"))
'test'
>>> '\t'.join(to_list_of_strings(["test", "test2"]))
'test\ttest2'
>>> '\t'.join(to_list_of_strings(range(4)))
'0\t1\t2\t3'
>>> '\t'.join(to_list_of_strings([1, 2, (3, 4)]))
'1\t2\t3\t4'
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top