簡體   English   中英

如何在Python 2.7中將“ yield”生成器結果存儲在列表中?

[英]How to store 'yield' generator result in a list in Python 2.7?

我有這樣的代碼:

import math    
nList = [[[0, 0, 0], [3, 2, 1]],\
     [[]],\
     [[1, 1, 12]],\
     [[0, 0, 0], [30000, 40, 3010], [32000, 40500, 7520], [0, 0, 10520]],\
     [[15340, 0, 0], [104300, 0, 3630], [434000, 4434000, 63460]]]

def calculate_length(x1, y1, x2, y2):
    return math.sqrt((x1-x2)**2 + (y1 - y2)**2)

def calculate_time (t1,t2):
    return abs(t1-t2)

def lengths(trace):
    previous_x, previous_y = 0, 0
    for index, point in enumerate(trace):
        if point:
            x, y, t = point
            if index > 0:
                yield calculate_length(x, y, previous_x, previous_y)
            previous_x, previous_y = x, y

我將如何在列表中存儲calculate_length(x, y, previous_x, previous_y)yield結果?

nList具有traces在它們與每個trace具有points與3個元素, [x,y,t] 我需要存儲每個跟蹤的長度,以便生成的輸出為:

all_lengths_list=[[3]],[[]],[[]],[[30000.02667],[40509.40138],[51616.37337]],[[88960],[4446240]]]

只需使用list

result = list(lengths(trace))

您不需要這些行繼續反斜杠-現代Python足夠聰明,可以知道列表定義不完整,因此它會自動為您執行行繼續。

另外,無需導入數學模塊即可計算平方根,您可以使用內置的冪運算符: ** 0.5

為了獲得所需的輸出,您需要一次將nList的跟蹤列表nList給生成器,將捕獲的數據捕獲到列表中,然后保存在all_lengths_list 可以在普通的for循環中完成此操作,但是使用列表理解更緊湊,如下面的代碼所示。 要顯示all_lengths_list的內容,我使用pprint模塊中的pprint() 它不是那么漂亮,但是比將它們全部放在一行上要好。 :)

#!/usr/bin/env python

from pprint import pprint

nList = [
    [[0, 0, 0], [3, 2, 1]],
    [[]],
    [[1, 1, 12]],
    [[0, 0, 0], [30000, 40, 3010], [32000, 40500, 7520], [0, 0, 10520]],
    [[15340, 0, 0], [104300, 0, 3630], [434000, 4434000, 63460]]
]

def calculate_length(x1, y1, x2, y2):
    return ((x1-x2)**2 + (y1 - y2)**2) ** 0.5

def calculate_time (t1,t2):
    return abs(t1-t2)

def lengths(trace):
    previous_x, previous_y = 0, 0
    for index, point in enumerate(trace):
        if point:
            x, y, t = point
            if index > 0:
                yield calculate_length(x, y, previous_x, previous_y)
            previous_x, previous_y = x, y

all_lengths_list = [list(lengths(trace)) for trace in nList]

pprint(all_lengths_list, indent=4)

輸出

[   [3.6055512754639891],
    [],
    [],
    [30000.026666654816, 40509.401377951763, 51616.373371247231],
    [88960.0, 4446240.8942836197]]

你可以通過獲得yield

l = lengths(nList)
next(l) # gives 1st yield
next(l) # gives 2nd

等等

要獲得所有列表

>>>list(lengths(nList))

該定義nList在你的代碼是不完整的,需要一對夫婦關閉]括號是語法正確。 同樣,一旦定義了一個開頭就開始了([如果隨后跨多個行,則不必顯式添加行繼續\\反斜杠字符。這使它們更易於編寫,並且更加整潔。自然的外觀。

通過該更正,您可以將lengths()函數yield值存儲在類似以下的list

all_lengths_list = [[length for length in lengths(trace)] for trace in nList]

或更簡潔地說,像這樣:

all_lengths_list = list((list(lengths(trace)) for trace in nList))

我還想提到一些可以簡化和優化代碼的事情。 除了sqrt() ,內置的math模塊還具有hypot()函數,該函數使您可以輕松地計算calculate_length()函數中的距離,並將加快速度,因為更多的數學運算將在模塊的中完成用C代碼代替Python。

我注意到的另一件事是,您的lengths()函數似乎過於復雜,可以通過使用Python的一些更高級的功能來大大簡化。 對於初學者來說,為什么不讓它返回點列表本身,而不是一次只產生一個點。

除此之外,Python的iterools模塊還包含許多基於它們的函數和配方,這些函數和配方使執行迭代操作(如計算)變得容易。 特別是,有一個生成器函數pairwise()配方,該函數可生成一個以兩個或兩個為一組的元組或成對的序列的元素—這使得它對計算距離非常有用,就像在lengths()所做的那樣。

以下是您代碼的修改版本,其中包含上述所有更正和建議。 我還在末尾添加了一些東西,以一種相當可讀的格式顯示結果。

import itertools
import math

nList = [[[0, 0, 0], [3, 2, 1]],
         [[]],
         [[1, 1, 12]],
         [[0, 0, 0], [30000, 40, 3010], [32000, 40500, 7520], [0, 0, 10520]],
         [[15340, 0, 0], [104300, 0, 3630], [434000, 4434000, 63460]]]

def calculate_length(x1, y1, x2, y2):
    return math.hypot(x1-x2, y1-y2)

def calculate_time (t1,t2):
    return abs(t1-t2)

def pairwise(iterable):  # see http://preview.tinyurl.com/mzbfqlt
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = itertools.tee(iterable)
    next(b, None)
    return itertools.izip(a, b)

def lengths(trace):
    return [calculate_length(x1, y1, x2, y2)
                for (x1, y1, t1), (x2, y2, t2) in pairwise(trace)]

all_lengths_list = list(lengths(trace) for trace in nList)

for pts_list, length_list in zip(nList, all_lengths_list):
    print('   points: {}\n'
          'distances: [{}]'.format(
              pts_list,
              ', '.join((format(length, '.2f') for length in length_list))))

輸出:

   points: [[0, 0, 0], [3, 2, 1]]
distances: [3.61]
   points: [[]]
distances: []
   points: [[1, 1, 12]]
distances: []
   points: [[0, 0, 0], [30000, 40, 3010], [32000, 40500, 7520], [0, 0, 10520]]
distances: [30000.03, 40509.40, 51616.37]
   points: [[15340, 0, 0], [104300, 0, 3630], [434000, 4434000, 63460]]
distances: [88960.00, 4446240.89]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM