在连续实例之前计算列表中的项目

时间:2014-03-20 10:30:45

标签: python python-3.x

我想在用户输入的连续数量的零之前计算数组中的项目数量。

['1', '0', '1', '0', '0', '0', '0', '0', '0', '0', 'E']

例如,如果用户输入3,则在连续三个零之前,列表中有三个项目。

目前我的代码会检查连续零的数量并根据它返回 - 如何更改此值以获得连续实例之前的项目值?

LargeBlock = max(sum(1 for _ in g) for k, g in groupby(line) if k == '0')

3 个答案:

答案 0 :(得分:5)

如果您首先将列表转换为字符串,则 更容易

  row = ['1', '0', '1', '0', '0', '0', '0', '0', '0', '0', 'E']
  seats = ''.join(row[:-1])

一旦成为字符串形式,就很容易搜索一个座位块:

  block = '0' * n
  location = s.find(block)

以下是单个函数中的所有代码:

def search(available, required):
    'Return the first available block of seats on a given row'
    row = available[-1]
    seats = ''.join(available[:-1])
    block = '0' * required
    i = seats.find(block)
    if i == -1:
        raise ValueError('no block large enough')
    return '%s%d-%s%d' % (row, i+1, row, i+required)


if __name__ == '__main__':
    print search(['1', '0', '1', '0', '0', '0', '0', '0', '0', '0', 'E'], required=3)

如果您想坚持原始的 itertools.groupby 方法,那么您需要在循环时跟踪位置和值。这是enumerate()的工作:

>>> def is_occupied(t):
        seat, occupied = t
        return occupied

>>> def seat_number(t):
        seat, occupied = t
        return seat

>>> required = 3
>>> row = ['1', '0', '1', '0', '0', '0', '0', '0', '0', '0', 'E']
>>> for occupied, groups in groupby(enumerate(row[:-1]), key=is_occupied):
        if occupied == '0':
            seats = list(map(seat_number, groups))
            if len(seats) >= required:
                print(seats[:required])

尽管 groupby()可以让你工作,但使用元组流(例如由 enumerate()生成的元组)是很棘手的。如果你的目标是清晰,那么跳过函数式编程组合技巧并且正常看是更好的事情。

这是一种直接的,非功能性的方法:

>>> cumulative_open = 0
>>> row_letter = row[-1]

>>> row = ['1', '0', '1', '0', '0', '0', '0', '0', '0', '0', 'E']
>>> required = 3

>>> row_letter = row[-1]
>>> cumulative_open = 0
>>> for i, occupied in enumerate(row[:-1], 1):
        if occupied == "1":
            cumulative_open = 0
            continue
        cumulative_open += 1
        if cumulative_open >= required:
            print('%s%d-%s%d' % (row_letter, i-required+1, row_letter, i))
            break
else:
    print("Not enough open seats")


E4-E6

答案 1 :(得分:1)

seats, wanted = ['1', '0', '1', '0', '0', '0', '0', '0', '0', '0', 'E'], 3
from itertools import groupby
for occ, grp in groupby(enumerate(seats[:-1], 1), key = lambda x: x[1]):
    if occ == '0':
        available = list(grp)
        if len(available) >= wanted:
            print([seats[-1] + str(item[0]) for item in available[:wanted]])

# ['E4', 'E5', 'E6']

答案 2 :(得分:0)

只是为了好玩....一个非常基本的剧院/行经理。

class Row():

    class SeatOccupiedException(Exception):
        pass

    def __init__(self, seats):
        """
        Create a theatre row with seats.

        seats ::= number of seats in the row
        """
        self.seats = [False]*seats

    def get_seats(self, group_size=1, empty=True):
        """
        Get seats from the row in chunks according to group size.
        Can get empty or non-empty seats.

        group_size ::= amount of seats needed.
        empty      ::= should the seats be empty or not?
        """
        ret = []
        current_seats = []

        for idx, seat in enumerate(self.seats, 1):
            if seat != empty:
                current_seats.append(idx)
            if len(current_seats) >= group_size:
                ret.append(current_seats[-group_size:])

        return ret

    def occupy_seats(self, seats):
        """
        Occupy some seats
        """
        for seat in seats:
            if self.seats[seat]:
                raise SeatOccupiedException()
            self.seats[seat] = True

    def vacate_seats(self, seats):
        """
        Vacate some seats
        """        
        for seat in seats:            
            self.seats[seat] = False

class Theatre():            

    class RowAlreadyExistsException(Exception):
        pass

    def __init__(self, rows=None, seats_per_row=10):
        """
        Create a theatre with rows, each row has seats.

        rows          ::= a list of the names for each row
        seats_per_row ::= number of seats in the row

        Examples:
        t = Theatre(['A', 'B', 'C']) 
        => produces a theatre with 3 rows (A,B,C) with 10 seats
        t = Theatre('ABCDEFG', 3) 
        => produces a theatre with 7 rows (A,B,C,D,E,F,G) with 3 seats
        """        
        self.rows = {}
        if rows:
            for row in rows:
                self.add_row(row, seats_per_row)

    def add_row(self, row_id, seats):
        """
        Add a row to the theatre

        row_id ::= the name of the row
        seats  ::= number of seats in the row
        """
        if row_id in self.rows:
            raise RowAlreadyExistsException()
        self.rows[row_id] = Row(seats)

    def get_available_seats(self, group_size, row_id=None):
        """
        Get all seats available for a group of a certain size
        Can specify a specific row or all of them

        group_size ::= how many available seats are needed
        row_id     ::= specify a certain row if desired
        """
        ret = {}

        def get_row(k):
            ret[k] = self.rows[k].get_seats(group_size)

        rows = [row_id] if row_id else self.rows
        for row_id in self.rows:
            get_row(row_id)

        return ret

    def occupy_seats(self, row_id, seats):
        """
        Occupy some seats
        """           
        self.rows[row_id].occupy_seats(seats)

    def vacate_seats(self, row_id, seats):
        """
        Vacate some seats
        """   
        self.rows[row_id].vacate_seats(seats)