2017-01-24 5 views
0

Ich habe eine Startnummer und eine Endnummer.
Aus diesen Zahlen muss ich eine Folge von Zahlen auswählen.
Die Sequenzen sind nicht immer gleich.Wie wählt man eine Zahlenfolge aus einer Liste?

Beispiel:

startnumber = 1 
endnumber = 32 

Ich brauche eine Liste von Zahlen mit einer bestimmten Reihenfolge
erstellen P. E.
3 Zahlen ja, 2 Zahlen nein, 3 Zahlen ja, 2 Zahlen nein .. etc

Erwartete Ausgabe:

[[1-3],[6-8],[11-13],[16-18],[21-23],[26-28],[31-32]] 

(am Ende gibt es nur 2 Zahlen verbleibenden (31 und 32))

Gibt es in Python eine einfache Möglichkeit, Zeilenfolgen aus einer Reihe von Zahlen auszuwählen?

+1

ich von 'annehmen [1-3]' Sie mean '[1,2,3]' –

+0

Ich verstehe nicht, wie Sie die Sequenz definiert haben.Mit "nicht immer gleich" meinst du zufällig? Muss die Anzahl der jeweils gezeichneten Sequenzen gleich sein? –

+0

Wer entscheidet über die Reihenfolge von "Take 3, Drop 2, Take 3, Drop 2, ..."? – Lagerbaer

Antwort

4
numbers = range(1,33) 
take = 3 
skip = 2 
seq = [list(numbers[idx:idx+take]) for idx in range(0, len(numbers),take+skip)] 
+0

das ist schlau. Bearbeiten Sie es einfach ein wenig, um das 'take 3, drop 2' Muster sichtbar und anpassbar zu machen und verstecken Sie den Trick beim Umwandeln der 33 in 35 ☺ –

+0

Auch das scheint Python 2 zu sein. In Python 3 würde man die 'range' zu' liste'. –

+0

Danke, das ist eine großartige Lösung. Es gibt jedoch eine Ausgabe mit Bereichen und Tupeln '[Bereich (1, 4), Bereich (6, 9), Bereich (11, 14), Bereich (16, 19), Bereich (21, 24), Bereich (26, 29), Bereich (31, 33)] 'und der zweite Wert im Bereich ist nicht der erwartete. – Reman

1

Rechnet man diese heraus:

def get_data(data, filterfunc=None): 
    if filterfunc is None: 
     filterfunc = lambda: True # take every line 

    result = [] 
    sub_ = [] 
    for line in data: 
     if filterfunc(): 
      sub_.append(line) 
     else: 
      if sub_: 
       result.append(sub_) 
       sub_ = [] 

    return result 

# Example filterfunc 
def example_filter(take=1, leave=1): 
    """example_filter is a less-fancy version of itertools.cycle""" 

    while True: 
     for _ in range(take): 
      yield True 
     for _ in range(leave): 
      yield False 

# Your example 
final = get_data(range(1, 33), example_filter(take=3, leave=2)) 

Wie in der docstring von example_filter angedeutet, wird die filterfunc für get_data wirklich nur ein True oder False basierend auf einem Anruf erwartet. Sie könnten dies leicht ändern die Signatur sein:

def filterfunc(some_data: object) -> bool: 

Damit Sie, ob basierend auf dem Wert (oder auch der Index) nehmen bestimmen oder zu verlassen, aber es dauert zur Zeit noch keine Argumente und nur Funktionen als weniger Magie itertools.cycle (da es seinen Wert auf Abruf zurückkehren sollte, nicht auf Iteration)

1
from itertools import islice 
def grouper(iterable, n, min_chunk=1): 
    it = iter(iterable) 
    while True: 
     chunk = list(islice(it, n)) 
     if len(chunk) < min_chunk: 
      return 
     yield chunk 

def pick_skip_seq(seq, pick, skip, skip_first=False): 
    if skip_first: 
     ret = [ x[skip:] for x in grouper(seq, pick+skip, skip+1) ] 
    else: 
     ret = [ x[:pick] for x in grouper(seq, pick+skip) ] 
    return ret 

pick_skip_seq(range(1,33), 3, 2) gibt gewünschte Liste.

In pick_skip_seq(seq, pick, skip, skip_first=False), seq ist Sequenz zu holen/skip aus, pick/skip nicht sind. von Elementen zum Aufnehmen/Überspringen, skip_first ist zu setzen True wenn ein solches Verhalten erwünscht ist.

liefert Chunks von n Elementen, es ignoriert letzte Gruppe, wenn es weniger als min_chunk Elemente hat. Es ist abgeleitet von Sachen gegeben in https://stackoverflow.com/a/8991553/1921546.

Demo:

# pick 3 skip 2 
for i in range(30,35): 
    print(pick_skip_seq(range(1,i), 3, 2)) 

# skip 3 pick 2 
for i in range(30,35): 
    print(pick_skip_seq(range(1,i), 3, 2, True)) 

Eine alternative Implementierung von pick_skip_seq:

from itertools import chain,cycle,repeat,compress 
def pick_skip_seq(seq, pick, skip, skip_first=False): 
    if skip_first: 
     c = cycle(chain(repeat(0, skip), repeat(1, pick))) 
    else: 
     c = cycle(chain(repeat(1, pick), repeat(0, skip))) 
    return list(grouper(compress(seq, c), pick)) 

Alle Dinge verwendet werden, hier dokumentiert: https://docs.python.org/3/library/itertools.html#itertools.compress

Verwandte Themen