2013-08-01 17 views
11

Python'da bir listeyi taramam gerekiyor. Ben dosyadan yüklemek açabiliyorum ve basit operasyon yapmak, ama şunları yapmaya çalıştığım:Bir liste tarama

L = [1,2,3,4,5,6,7,8] 

birinci elemanın başlayarak aşağıdaki çıktıyı üretmek istiyorum:

1 
    2,3,4,5,6,7,8 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
2 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
3 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
4 
    5,6,7,8 
    6,7,8 
    7,8 
    8 

ve bunun gibi.

Böyle bir şey çalışıyordu: Beni

fo = open(sys.argv[1], 'r') 
L = fo.readlines() 
for i in range(len(L)): 
    print str(L[i]) 
    for j in range(len(L)-1-i): 
     print '...' + str(L[i+j+1]) 

yardımcı olabilir mi?

+0

Kafam karıştı ... Listeyi 1,3,4,5,6,7 ve 8'den başlayarak yazdırıyorsunuz, sonra 2, 4, 5, 6, 7, 8, 3, 5, ile başlıyorsunuz. 7 ... Deseni görmüyorum, bunu açık yapabilir misiniz? – Jblasco

+0

Sadece "open (sys.argv [1]," r ") ile fo: # fo ile bir şeyler yapmanın daha iyi olacağını eklemeyi tercih ediyorum çünkü bu şekilde dosya otomatik olarak kapatılır. onunla uğraşırken bir hata oluşur. Sadece iyi bir uygulama. – rlms

cevap

13

Bu nasıl? Güzel ve basit okumak için: Liste temp boş değilken


while temp

>>> for i, j in enumerate(L): 
...  print L[i] 
...  temp = map(str, L[j:]) 
...  while temp: 
...    print ' ', ','.join(temp) 
...    temp = temp[1:] 
... 
1 
    2,3,4,5,6,7,8 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
2 
    3,4,5,6,7,8 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
3 
    4,5,6,7,8 
    5,6,7,8 
    6,7,8 
    7,8 
    8 
... 
anlamına gelir. Liste


Bir başka not tamsayılar dolu (ve böylece str.join yöntem işe yaramaz) olduğu için biz burada map(str, L[j:]) aramak zorunda dosyalarla çalışırken, bir with deyimini kullanmak daha pythonic var:

with open(sys.argv[1], 'r') as fo: 
    L = fo.readlines() 
+0

Çok güzel, ama kullanıcının istediği nedir? Yukarıdaki yorumuma bakın. – Jblasco

+2

@Jblasco – TerryA

+0

sorusunda verdiği çıktıyla özdeş görünüyor. Şimdi haklısınız. Aralarında düzenlenmiştir. – Jblasco

4

Haidro yanıtı istenen çıktıyı üretirken, bunun sağlanan görevi yapmak için oldukça verimsiz bir algoritma olduğunu söylemeliyim.

hızlı analizi:

for i, j in enumerate(L):   # loop number 1, for i from 1 to N 
    print L[i] 
    temp = map(str, L[j:])   
    while temp:     # nested loop number 2, for j from i to N 
     print ' ', ','.join(temp) # nested loop number 3, for k from j to N 
     temp = temp[1:] 

böyle basit bir görev için çok fazla iş var. Bunu sadece bir kez ve daha sonra dize katılmadan, çok simplier ve daha hızlı yapılabilir düşünüyorum baskı altdizgelerin (DCM, yorum olarak bahsedilen biz dizede elemanların konumlarını ön hesaplama gerektiğini keyfi sayıları yazdırmak için muktedir gibi):

s = ",".join(map(str, l))     # creating string 
p = [len(str(x)) + 1 for x in l]   # calculating length of each element 
p = [sum(p[:i]) for i in range(len(p))] # calculating positions with rolling total 
for i in range(len(l)):     # loop number 1 
    print l[i] 
    for j in range(i + 1, len(l)):   # nested loop number 2 
     print ' ', s[p[j]:] 

İşte yürütme sürelerinin hızlı bir profili (Haol koduyla worker1 ve madeni ile worker2 işlevi oluşturuyorum).

>>> from timeit import timeit 

>>> timeit("worker1(l)", "from testSO import worker1, l", number=10) 
0.0016222212978796024 
>>> timeit("worker1(l*10)", "from testSO import worker1, l", number=10) 
0.33153371422580324 
>>> timeit("worker1(l*100)", "from testSO import worker1, l", number=10) 
163.25908817145972 

O O(N^3)

>>> timeit("worker2(l)", "from testSO import worker2, l", number=10) 
0.0006974355000011201 
>>> timeit("worker2(l*10)", "from testSO import worker2, l", number=10) 
0.03448374103493279 
>>> timeit("worker2(l*100)", "from testSO import worker2, l", number=10) 
4.446190059150922 

gibi büyür O değil

O(N^2) benzese büyür Ben orijinal olduğunu düşünüyorum: Eğer giriş uzunluğu N artırmak yürütme zamanı nasıl büyür görebilirsiniz soru, performans kritik görevine benziyor, ama sanırım insanlar algoritmanın neden beklediğinden daha yavaş olabileceğini görüyorsa iyi olur.

+1

Bu daha iyi bir performansa sahiptir, ancak yazılı olarak oldukça az dayanıklıdır. Sayıların uzunluğu her zaman 1 değilse, beklenen sonuçları vermez. – DSM

+0

@DSM, çok iyi bir nokta, bunu özledim, kontrol edeceğim –

+0

@DSM, öğelerin önceden hesaplanmış konumları ile cevabı değiştirdi –

İlgili konular