【问题标题】:list with infinite elments具有无限元素的列表
【发布时间】:2012-12-17 07:55:46
【问题描述】:

我需要对两个单独的无限列表数字进行操作,但找不到在 python 中生成、存储和操作它的方法。

考虑到内存和时间的最小使用,任何人都可以建议我一种处理无限算术渐进或任何系列的方法以及如何对它们进行操作。

提前感谢大家的建议。

【问题讨论】:

  • 看看 scipy 或 pandas
  • 为什么不只是itertools.count? OP 想要一个算术级数。
  • 要存储无限列表,您需要一个非常大的硬盘。

标签: python


【解决方案1】:

您正在寻找 python generator 代替:

def infinitenumbers():
    count = 0
    while True:
        yield count
        count += 1

itertools 包附带一个预构建的count generator

>>> import itertools
>>> c = itertools.count()
>>> next(c)
0
>>> next(c)
1
>>> for i in itertools.islice(c, 5):
...     print i
...
2
3
4
5
6

【讨论】:

    【解决方案2】:

    这就是iterator 的用武之地。你不能有一个无限的数字列表,但你可以有一个无限的迭代器。

    import itertools
    arithmetic_progression = itertools.count(start,step) #from the python docs
    

    Python2 的文档可以在here找到

    【讨论】:

      【解决方案3】:

      我有另一个python3解决方案(阅读SICP第3.5章)

      class Stream:
      def __init__(self, head, tail):
              self.head = head
              self.tail = tail
              self.memory = None
              self.isDone = False
      def car(self):
              return self.head
      def cdr(self):
              if self.isDone:
                      return self.memory
              self.memory = self.tail()
              self.isDone = True
              return self.memory
      def __getitem__(self, pullFrom):
              if pullFrom < 1 or self.memory == []:
                      return []
              return [self.car()] + self.cdr()[pullFrom - 1]
      def __repr__(self):
              return "[" + repr(self.car()) + " x " + repr(self.tail) + "]"
      def map(self, func):
              if self.memory == []:
                      return []
              return Stream(func(self.car()), lambda: Stream.map(self.cdr(), func))
      def from_list(lst):
          if lst == []:
              return []
          return Stream(lst[0], lambda:
                        Stream.from_list(lst[1:]))
      def filter(self, pred):
          if self.memory == []:
              return []
          elif pred(self.car()):
              return Stream(self.car(), lambda: Stream.filter(self.cdr(), pred))
          else:
              return self.cdr().filter(pred)
      def sieve(self):
          return Stream(self.car(), lambda: self.cdr().filter(lambda n: n % self.car() > 0).sieve())
      def foreach(self, action, pull = None):
          if pull is None:
              action(self.car())
              self.cdr().foreach(action, pull)
          elif pull <= 0:
              return
          else:
              action(self.car())
              self.cdr().foreach(action, pull-1)and run:
      
      a = Stream(0, lambda: a.map((lambda x: x + 1)))
      print(a[10])
      

      返回: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].

      但是流是惰性求值的,所以:

      >>> a = Stream(0, lambda: a.map((lambda x: x + 1)))
      >>> print(a)
      

      打印:

      [0 x [...]]

      【讨论】:

        【解决方案4】:

        要创建一个类似于“可变”无限列表的对象,您可以在一个类中重载__getitem____setitem__ 方法:

        class infinite_list():
            def __init__(self, func):
                self.func = func
                self.assigned_items = {}
            def __getitem__(self, key):
                if key in self.assigned_items:
                    return self.assigned_items[key]
                else:
                    return self.func(key)
            def __setitem__(self, key , value):
                self.assigned_items[key] = value
        

        然后,您可以使用 lambda 表达式初始化“无限列表”并修改列表中的一项:

        infinite_thing = infinite_list(lambda a: a*2)
        
        print(infinite_thing[1]) #prints "2"
        infinite_thing[1] = infinite_thing[2]
        print(infinite_thing[1]) #prints "4"
        

        同样,可以创建一个“infinite dictionary”,为每个缺失的键提供一个默认值。

        【讨论】:

          【解决方案5】:

          也许生成无限级数的自然方法是使用生成器:

          def arith(a, d):
             while True:
               yield a
               a += d
          

          可以这样使用:

          print list(itertools.islice(arith(10, 2), 100))
          

          【讨论】:

            【解决方案6】:

            我的解决办法是:

            from hofs import *
            def cons_stream(head,tail):
                return [head,tail,False,False]
            def stream_cdr(strm):
                if strm[2]:
                    return strm[3]
                strm[3] = strm[1]()
                strm[2] = True
                return strm[3]
            def show_stream(stream, num = 10):
                if empty(stream):
                    return []
                if num == 0:
                    return []
                return adjoin(stream[0], show_stream(stream_cdr(stream), num - 1))
            def add_streams(a , b):
                if empty(a):
                    return b
                if empty(b):
                    return a
                return cons_stream(a[0] + b[0] , lambda : add_streams( stream_cdr(a), stream_cdr(b)))
            def stream_filter( pred , stream ):
                if empty(stream):
                    return []
                if pred(stream[0]):
                    return cons_stream(stream[0], lambda : stream_filter(pred, stream_cdr(stream)))
                else:
                    return stream_filter( pred , stream_cdr( stream ))
            def sieve(stream):
                return cons_stream(stream[0] , lambda : sieve(stream_filter(lambda x : x % stream[0] > 0 , stream_cdr(stream))))
            ones = cons_stream(1, lambda : ones)
            integers = cons_stream(1, lambda : add_streams(ones, integers))
            primes = sieve(stream_cdr(integers))
            print(show_stream(primes))
            

            复制上面的 Python 代码。 当我尝试它时,我得到了 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] ,这是无限素数列表中的 10 个。

            【讨论】:

            • 哦,也是在 hofs.py 中输入:
            • 'def empty(data): return data == [] def adjoin(value,data): result = [value] result.extend(data) return result def map(func, data): if empty(data): return [] else: return adjoin(func(data[0]), map(func, data[1:])) def keep(pred, data): if empty(data): return [] elif pred(data[0]): return adjoin(data[0], keep(pred, data[1:])) else: return keep(pred, data[1:])'
            【解决方案7】:

            你需要 hofs.py 是

            def empty(data):
                return data == []
            
            def adjoin(value,data):
                result = [value]
                result.extend(data)
                return result
            
            def map(func, data):
                if empty(data):
                    return []
                else:
                    return adjoin(func(data[0]), map(func, data[1:]))
            
            def keep(pred, data):
                if empty(data):
                    return []
                elif pred(data[0]):
                    return adjoin( data[0] , keep(pred, data[1:]))
                else:
                    return keep(pred, data[1:])
            

            【讨论】:

            • 添加一些解释,说明此答案如何帮助 OP 解决当前问题
            【解决方案8】:

            我假设您想要一个范围内的无限数列表。我有类似的问题,这是我的解决方案:

            c = 0
            step = 0.0001 # the difference between the numbers
            limit = 100 # The upper limit 
            myInfList = []
            while c <= limit:
                myInfList.append(c)
                c = c + step
            print(myInfList)
            

            【讨论】:

            • 您的 while 循环永远不会达到限制,因为您需要执行 c = c + stepc += step 而不仅仅是 c + step
            • 在什么意义上这是一个无限列表?
            • 感谢@MarkDickinson,刚刚解决了这个问题。
            • 这只是让你有很多数字,只要你的限制和步骤允许。看起来最初的问题是要有一个有限制的 AP,但这需要一个步骤@MarkDickinson
            猜你喜欢
            • 1970-01-01
            • 2012-02-13
            • 1970-01-01
            • 2014-11-09
            • 2013-02-27
            • 2013-09-28
            • 1970-01-01
            • 1970-01-01
            • 2014-02-17
            相关资源
            最近更新 更多