私は同じ長さの2つのリストを持っています。私は1つのリストの条件をチェックしたい。条件が真であれば、他のリストで非常にメモリ/処理が集中した関数を実行します。リスト内包で3万回の致命的な機能を実行することを避けるにはどうすればよいですか?
私の最初の試みはほどだった:
records = [(a, deadly_func(b)) for a, b in zip(listA, listB) if a == "condition"]
これはすぐに私のデスクトップ上のすべてのメモリを割り当てられ、私はそれを殺した前に、しばらくの間に行ってきました。明らかに、listBのすべての30,000項目についてdeadly_func(b)を実行しましたが、リストBを約30項目までフィルタリングするためにif文を使用することが意図されていました。
私は作業バージョンを作ることができた:なぜ私の最初の試みはうまくいきませんでした
records = [(a, i) for a, i in zip(listA, range(len(listB)) if a == "condition"]
records = [(a, deadly_func(listB[i]) for a, i in records]
?この作品を作るためのより無邪気な方法がありますか?
編集:いただきありがとうございます。
import shapefile, shapely.geometry as shpgeo
lat = 42.3968243
lon = -71.0313479
sf = shapefile.Reader("/opt/ziplfs/tl_2014_us_zcta510.shp")
records = [(r[0], shpgeo.shape(s.__geo_interface__)) for r, s in zip(sf.records(), sf.shapes()) if haversine(lon, lat, float(r[8]), float(r[7])) < 10]
半正矢()LATと長い二対のを取って、ユーザ製半正矢関数であり、キロメートルに距離を返す:ここで働いてなかった両バージョン
ための実際のコードです。
from math import sqrt, sin, cos, radians, asin
def haversine(lon1, lat1, lon2, lat2):
"""
Calculate the great circle distance between two points
on the earth (specified in decimal degrees). Return is in kilometers
"""
# convert decimal degrees to radians
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
# haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
r = 6371 # Radius of earth in kilometers. Use 3956 for miles
return c * r
シェープファイル(「tl_2014_us_zcta510.shp」)は国勢調査局から、米国内のすべてのジップコードです。あなたが本当にシェイプファイルを愛している場合はhereをダウンロードし、ハードドライブに800 MBのファイルを用意してください。
このスクリプトでは、アメリカのすべての郵便番号を表すタプルのリストを、チェルシー(マサチューセッツ州)から10km以内のセントロイドで返します。作業バージョンについては
、持つレコードラインを置き換える:
records = [(r[0], i) for r, i in zip(sf.records(), range(len(sf.records()))) if haversine(lon, lat, float(r[8]), float(r[7])) < 10]
shapes = [shpgeo.shape(sf.shape(i).__geo_interface__) for r, i in records]
私はいくつかのタイミングテストをしました。 「非稼働」バージョン:
$ python test.py
Time Elapsed: 0:00:14.221533
$ python test.py
Time Elapsed: 0:00:14.637827
$ python test.py
Time Elapsed: 0:00:14.253425
と作業バージョン:
$ python test.py
Time Elapsed: 0:00:01.887987
$ python test.py
Time Elapsed: 0:00:01.886635
$ python test.py
Time Elapsed: 0:00:01.982547
たぶんと言うあたりの「致命的」、しかし重要ではありませんあなたは30K回繰り返します。
をあなたは一度も致命的な機能を実行したいと思う理由:
また、あなたは追加することにより、デバッグのために最初の1000にご入力のサイズを小さくすることができますか? –
@JohnColemanは 'a!=" condition "'の場合にのみ関数が致命的であると言うことができます: – Dekel
リストの種類の例がありますか?私は 'print'といくつかの小さなコンテナを使ってこれを複製しようとしました。 – mwchase