2012-10-26 11 views
6

Mam skoordynowaną listę pamięci w pythonie A[row,col,value] do przechowywania wartości zerowych.Pierwsze pozycje na liście wewnętrznej sprawnie, jak to możliwe

Jak mogę uzyskać listę wszystkich indeksów wierszy? Spodziewałem się, że ta A[0:][0] zadziała, gdy print A[0:] wydrukuje całą listę, ale print A[0:][0] drukuje tylko .

Powód, dla którego pytam, to efektywne obliczenie liczby niezerowych wartości w każdym wierszu , tj. iterowanie po range(0,n), gdzie n jest całkowitą liczbą rzędów. To powinno być o wiele tańsze: niż moja obecna metoda for i in range(0,n): for j in A: ....

Coś jak:

c = [] 
# for the total number of rows 
for i in range(0,n): 
    # get number of rows with only one entry in coordinate storage list 
    if A[0:][0].count(i) == 1: c.append(i)     
return c 

Over:

c = [] 
# for the total number of rows 
for i in range(0,n): 
    # get the index and initialize the count to 0 
    c.append([i,0]) 
    # for every entry in coordinate storage list 
    for j in A: 
     # if row index (A[:][0]) is equal to current row i, increment count 
     if j[0] == i: 
      c[i][1]+=1 
return c 

EDIT:

Korzystanie odpowiedź Junuxx'S, this question i this post wymyśliłem następujący (na powrocie numer z pojedynczych wierszy), który jest znacznie szybszy dla moje bieżące problemy mają rozmiar A niż moja pierwotna próba. Jednak wciąż rośnie wraz z liczbą wierszy i kolumn. Zastanawiam się, czy jest możliwe, aby nie trzeba iterować ponad A, ale po prostu upto n?

# get total list of row indexes from coordinate storage list 
row_indexes = [i[0] for i in A] 
# create dictionary {index:count} 
c = Counter(row_indexes)  
# return only value where count == 1 
return [c[0] for c in c.items() if c[1] == 1] 
+1

@larsman: Zakładam, że A jest lista trójek. – Junuxx

+0

Tak, masz to. –

+1

Czy możesz napisać prosty, nieefektywny, działający przykład tego, co próbujesz zrobić? Uważam, że sformułowanie pytania jest naprawdę mylące i żaden z twoich przykładowych bloków kodu nie robi tego samego ...? – dbr

Odpowiedz

10

ten powinien zrobić:

c = [x[0] for x in A] 

To lista zrozumienie, że zajmuje pierwsze (pod) elementem każdego elementu A.

+0

To działa znacznie lepiej niż moje oryginalne rozwiązanie. Proszę zobaczyć moją edycję, czy to możliwe, że I nie powtórzy? Bardzo doceniane! –

+0

Jeśli A jest bardzo duże, ale elementy A mają tylko trzy elementy, bardziej wydajne może być przechowywanie trzech list, 'wierszy',' kolumn' i 'wartości'. Będziesz mógł natychmiast uzyskać wszystkie numery wierszy i nadal mieć dostęp do pojedynczego wpisu, używając tego samego indeksu dla wszystkich trzech list (są one wyrównane). Jeśli zarówno A, jak i podlisty są długie, lepiej byłoby użyć prawdziwej, dwuwymiarowej struktury danych, takiej jak dostarczona przez numpy (patrz odpowiedź Jona Clementsa) zamiast zagnieżdżonych list. – Junuxx

4

Dla efficieny i rozszerzonych plasterki, można użyć numpy - co biorąc pod uwagę Twój przykład wydaje się dobrym pomysłem:

import numpy as np 
yourlist = [ 
    [0, 0, 0], 
    [0, 1, 1], 
    [1, 0, 2] 
] 
a = np.array(yourlist) 
print a[:,0] 
# [0 0 1] 
bc = np.bincount(a[:,0]) 
# array([2, 1]) 
count = bc[bc==1].size 
# 1 
# or... (I think it's probably better...) 
count = np.count_nonzero(bc == 1) 
+0

Nie mogę uzyskać twojego przykładu do pracy ... 'type (mylist [0] [0])' zwraca 'int',' type (a [0] [0]) 'zwraca' numpy.float64' po 'a = numpy.array (mylist) 'gdy próbuję' bincount (a [:, 0]) 'Otrzymuję' TypeError: array nie można bezpiecznie odrzucić do wymaganego typu 'Próbowałem' bc = numpy.bincount (numpy.arange (a [:, 0], dtype = numpy.int)) ', a błąd to' TypeError: tylko tablice długości-1 mogą zostać przekonwertowane na skalary Pythona'' –

+0

@sudo_o Nie wiem co powiedzieć na ten temat - po 'np.array' (nie' np.arange') kończę za pomocą 'type (a [0] [0])' i wszystko inne działa ... –

Powiązane problemy