Trích xuất các phần tử của danh sách ở các vị trí lẻ


100

Vì vậy, tôi muốn tạo một danh sách là một danh sách con của một số danh sách hiện có.

Ví dụ,

L = [1, 2, 3, 4, 5, 6, 7], Tôi muốn tạo một danh sách licon lichứa tất cả các phần tử Lở các vị trí lẻ.

Trong khi tôi có thể làm điều đó bằng cách

L = [1, 2, 3, 4, 5, 6, 7]
li = []
count = 0
for i in L:
    if count % 2 == 1:
        li.append(i)
    count += 1

Nhưng tôi muốn biết liệu có cách nào khác để làm điều tương tự một cách hiệu quả và ít bước hơn không.


@WaleedKhan: Tại sao anh ấy cần liệt kê những điều dễ hiểu trong một câu hỏi?
Tamara Wijsman

1
@TomWijsman: Liệt kê toàn bộ . ETA: Bỏ qua điều đó: Tôi đã tìm kiếm xung quanh và phát hiện ra câu trả lời này của bạn cho thấy bạn đang nói đùa. Đặt một khuôn mặt cười vào lần sau!
David Robinson

2
@DavidRobinson: Nhưng những người khác có thể nói điều đó không, có thể không hiểu rõ ý của anh ấy bằng hai từ mơ hồ. Chỉ đâm đầu vào đây với một số nhận xét, vì vậy mọi người thiết lập và viết nội dung tốt hơn; và để tránh bỏ OP hoặc khách tránh khỏi thất bại ... :)
Tamara Wijsman

Câu trả lời:


229

Giải pháp

Có, bạn có thể:

l = L[1::2]

Và đây là tất cả. Kết quả sẽ chứa các phần tử được đặt trên các vị trí sau ( 0-based, vì vậy phần tử đầu tiên ở vị trí 0, thứ hai ở vị trí , 1v.v.):

1, 3, 5

vì vậy kết quả (số thực) sẽ là:

2, 4, 6

Giải trình

Các [1::2]cuối cùng chỉ là một ký hiệu cho danh sách cắt. Thông thường nó ở dạng sau:

some_list[start:stop:step]

Nếu chúng tôi bỏ qua start, mặc định ( 0) sẽ được sử dụng. Vì vậy, phần tử đầu tiên (tại vị trí 0, vì các chỉ mục được 0dựa trên cơ sở) sẽ được chọn. Trong trường hợp này, phần tử thứ hai sẽ được chọn.

Vì phần tử thứ hai bị bỏ qua, phần tử mặc định đang được sử dụng (phần cuối của danh sách). Vì vậy, danh sách đang được lặp lại từ phần tử thứ hai đến cuối .

Chúng tôi cũng cung cấp đối số thứ ba ( step) là 2. Có nghĩa là một phần tử sẽ được chọn, phần tử tiếp theo sẽ bị bỏ qua, v.v.

Vì vậy, tóm lại, trong trường hợp này [1::2]có nghĩa là:

  1. lấy phần tử thứ hai (nhân tiện, là một phần tử lẻ, nếu bạn đánh giá từ chỉ mục),
  2. bỏ qua một phần tử (bởi vì chúng tôi có step=2, vì vậy chúng tôi đang bỏ qua một phần tử, trái ngược với step=1phần tử mặc định),
  3. lấy phần tử tiếp theo,
  4. Lặp lại các bước 2.-3. cho đến khi đạt đến cuối danh sách,

CHỈNH SỬA : @PreetKukreti đã đưa ra một liên kết cho một lời giải thích khác về ký hiệu cắt danh sách của Python. Xem tại đây: Giải thích ký hiệu lát cắt của Python

Bổ sung - thay thế bộ đếm bằng enumerate()

Trong mã của bạn, bạn tạo và tăng bộ đếm một cách rõ ràng. Trong Python, điều này là không cần thiết, vì bạn có thể liệt kê thông qua một số có thể lặp lại bằng cách sử dụng enumerate():

for count, i in enumerate(L):
    if count % 2 == 1:
        l.append(i)

Ở trên phục vụ chính xác mục đích giống như mã bạn đang sử dụng:

count = 0
for i in L:
    if count % 2 == 1:
        l.append(i)
    count += 1

Tìm hiểu thêm về mô phỏng forvòng lặp với bộ đếm trong Python: Truy cập chỉ mục trong vòng lặp 'for' trong Python


@TomWijsman nhìn này câu hỏi cho cú pháp python cắt sự hiểu biết
Preet Kukreti

Câu hỏi yêu cầu các vị trí lẻ. Điều này cho các vị trí chẵn (0,2,4,6); có vẻ như OP muốn các chỉ số (1,3,5), sẽ được cung cấp bởi [1,2,3,4,5,6,7][1::2].
Marcin

@Marcin: Vâng, tôi thực sự đã đưa ra cùng một kết luận (xem phần đính chính). Điều này được đưa ra sau khi tôi đã đọc kỹ mã OP. Vấn đề dẫn đến việc lập chỉ mục dựa trên cơ sở khác nhau (đối với tôi phần tử " lẻ " có nghĩa là phần tử đầu tiên , đối với OP dường như là phần tử thứ hai , vì vậy được lập chỉ mục tại 1).
Tadeck

1
@TomWijsman: Tôi xin lỗi, tôi không nhận thấy bạn đã thay đổi những gì. Thật vậy, có một liên kết, nhưng nó dẫn đến dự án Numarray, không phải đến việc listcắt lát của Python . Nó khác một chút, đặc biệt là vì listlát cắt của nó không giữ tham chiếu đến danh sách ban đầu (trong Numarray, bạn cần phải gọi rõ ràng .copy()để có thứ gì đó không tham chiếu đến mảng ban đầu). Nhưng thật vui khi có một số người đọc có thể tốt hơn. Bạn có vui lòng đăng liên kết này trong nhận xét để tôi có thể tán thành nó và nó sẽ xuất hiện ngay bên dưới câu trả lời không?
Tadeck

@Tadeck "Các chỉ số được đánh số lẻ" khá tự nhiên có nghĩa là các chỉ số là số lẻ.
Marcin

12

Đối với các vị trí lẻ , bạn có thể muốn:

>>>> list_ = list(range(10))
>>>> print list_[1::2]
[1, 3, 5, 7, 9]
>>>>

3

Tôi thích cách hiểu Danh sách vì cú pháp Toán học (Tập hợp) của chúng. Vậy làm thế nào về điều này:

L = [1, 2, 3, 4, 5, 6, 7]
odd_numbers = [y for x,y in enumerate(L) if x%2 != 0]
even_numbers = [y for x,y in enumerate(L) if x%2 == 0]

Về cơ bản, nếu bạn liệt kê trên một danh sách, bạn sẽ nhận được chỉ mục xvà giá trị y. Những gì tôi đang làm ở đây là đặt giá trị yvào danh sách đầu ra (chẵn hoặc lẻ) và sử dụng chỉ mục xđể tìm xem điểm đó có phải là lẻ ( x%2 != 0) hay không.


1
Không nên liệt kê (L) thay vì liệt kê (mục)?
ab123

0

Bạn có thể sử dụng toán tử AND bitwise &. Hãy xem bên dưới:

x = [1, 2, 3, 4, 5, 6, 7]
y = [i for i in x if i&1]
>>> 
[1, 3, 5, 7]

Toán tử AND bitwise được sử dụng với 1, và lý do nó hoạt động vì số lẻ khi được viết trong hệ nhị phân phải có chữ số đầu tiên là 1. Hãy kiểm tra

23 = 1 * (2**4) + 0 * (2**3) + 1 * (2**2) + 1 * (2**1) + 1 * (2**0) = 10111
14 = 1 * (2**3) + 1 * (2**2) + 1 * (2**1) + 0 * (2**0) = 1110

Phép toán AND với 1 sẽ chỉ trả về 1 (1 trong hệ nhị phân cũng sẽ có chữ số cuối cùng là 1), iff giá trị là số lẻ.

Kiểm tra trang Toán tử Bitwise Python để biết thêm.

Tái bút: Bạn có thể sử dụng phương pháp này một cách chiến thuật nếu bạn muốn chọn các cột chẵn và lẻ trong khung dữ liệu. Giả sử tọa độ x và y của các điểm chính trên khuôn mặt được cho dưới dạng cột x1, y1, x2, v.v. ... Để chuẩn hóa tọa độ x và y với các giá trị chiều rộng và chiều cao của mỗi hình ảnh, bạn chỉ cần thực hiện

for i in range(df.shape[1]):
    if i&1:
        df.iloc[:, i] /= heights
    else:
        df.iloc[:, i] /= widths

Điều này không liên quan chính xác đến câu hỏi nhưng đối với các nhà khoa học dữ liệu và kỹ sư thị giác máy tính, phương pháp này có thể hữu ích.

Chúc mừng!


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.