【问题标题】:Python 3 turn range to a listPython 3 将范围转换为列表
【发布时间】:2012-07-13 20:50:22
【问题描述】:

我正在尝试列出一个包含数字1-1000 的列表。显然,写/读这会很烦人,所以我试图制作一个包含范围的列表。在 Python 2 中似乎:

some_list = range(1,1000)

会起作用,但在 Python 3 中,范围类似于 Python 2 的 xrange

谁能提供一些对此的见解?

【问题讨论】:

  • 另外,some_list[i] == i+1,所以你可能并不真的需要一个列表。
  • @RikPoggi。例如,可能需要为绘图函数提供一个列表。有时一个范围就足够了,但一个范围不能被连接(是不可变的),所以如果你需要为所有正在绘制的列表添加一个默认的起始值,那也需要变成一个列表。

标签: python python-3.x list range


【解决方案1】:

您确实不需要在列表中使用数字 1-1000。但如果出于某种原因您确实需要这些数字,那么您可以这样做:

[i for i in range(1, 1001)]

简述列表理解:

上面的列表理解转化为:

nums = []
for i in range(1, 1001):
    nums.append(i)

这只是列表解析语法,虽然来自 2.x。我知道这将在 python 3 中工作,但不确定是否也有升级的语法

范围开始包括第一个参数;但结束于,不包括第二个参数(当提供 2 个参数时;如果第一个参数不存在,它将从 '0' 开始)

range(start, end+1)
[start, start+1, .., end]

【讨论】:

  • 为什么要理解?只是:list(range(1000))
  • 谢谢!你介意解释一下为什么它是 i for i in... 而不是简单地 for i in?
  • 我没用过python3。所以我不完全确定它是如何工作的。我知道理解会起作用,但不是 100% 在选角上。但如果铸造有效,那么你是对的,而且你的方式更符合 Python 风格。
  • @inspectorG4dget:这不是“铸造”,而是调用list() constructor with an iterablelist() 构造函数知道如何在给定任何可迭代对象时创建新列表。
  • @inspectorG4dget: list(range(1000)) 将在 python3 中工作,就像在 python2 中的 list(xrange(1000)) 一样
【解决方案2】:

你可以从范围对象构造一个列表:

my_list = list(range(1, 1001))

这也是你在 python2.x 中使用生成器的方式。一般来说,您可能不需要列表,因为您可以更有效地获得my_list[i] 的值(i + 1),如果您只需要迭代它,您可以退回到range .

还要注意,在 python2.x 上,xrange 仍然是可索引的1。这意味着python3.x上的range也有同样的属性2

1print xrange(30)[12] 适用于 python2.x

2与python3.x中的1类似的语句是print(range(30)[12]),也可以。

【讨论】:

  • 我会说“construct”或“build”(或者可能是“materialise”)——因为你没有将生成器“转换”(因此)到列表,你正在创建一个新的从恰好是生成器的数据源中列出对象......(但假设只是分裂头发,而不是 100% 确定我喜欢什么)
  • 我对“构造”的 +1,因为它与其他 OO 语言一致。 list(arg) 在其他语言中被理解为调用list 类的构造函数。实际上,这也是 Python 的情况。对象是在构造期间填充(如在 C++ 案例中)还是仅在第一个自动调用方法期间填充(如 Python __init__() 方法)的争论不能改变基本的抽象思想。我的观点是列表构造函数采用迭代器并用返回值填充列表
  • @pepr -- 是的,我同意。构造可能是最好的词。一言以蔽之。不保证会调用__init__。 (来自__new__ { docs.python.org/reference/datamodel.html#object.__new__ } 的文档)“如果 __new__() 没有返回 cls 的实例,则不会调用新实例的 __init__() 方法。”
  • 为什么它在 jupyter notebook 中出现错误并且在 shell 中工作正常?错误:'range' object is not callable
  • 如何将np.nan 添加到此列表中?
【解决方案3】:

其实如果你想要1-1000(含),使用range(...)函数,参数为1和1001:range(1, 1001),因为range(start, end)函数从start到(end-1),含。

【讨论】:

    【解决方案4】:

    在 Python 3.x 中,range() 函数有自己的类型。所以在这种情况下你必须使用迭代器

    list(range(1000))

    【讨论】:

    • "在这种情况下你必须使用迭代器"?这到底是什么意思?
    • 我正在使用 python 3.7 并尝试 x=list(range(1000)) 但收到错误 TypeError: 'list' object is not callable
    • @Earthshaker 你一定有错字,比如list(range(1000))()
    【解决方案5】:

    在 Pythons list(range(10)) 来创建超出范围的列表(通常是任何可迭代的)。

    在 Python 3.5 中引入的另一种替代方法是在列表文字 [] 中使用 *

    >>> r = range(10)
    >>> l = [*r]
    >>> print(l)
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    虽然这相当于list(r),但它是文字语法,而且不涉及函数调用这一事实确实让它执行得更快。如果您需要编码高尔夫,它的字符也更少:-)

    【讨论】:

    • 要清楚,你仍然可以单行它:[*range(10)] 适用于当你不需要 range 用于任何目的但初始化 list 时。旁注:解包概括中我最喜欢(好吧,不是真的)部分是空的sets 现在有一个字面语法{*()},或者我称之为独眼猴子运算符。 ;-)
    • @ShadowRanger 这就是我最初考虑编写它的方式。为了不让 Python 新用户感到困惑,我决定写得更详细一点:-)
    【解决方案6】:

    其实这是 Python3 相对于 Python2 的回溯。当然,使用 range() 和 xrange() 的 Python2 比分别使用 list(range()) 和 range() 的 Python3 更方便。原因是Python3的原设计者经验不是很丰富,他们只考虑了很多初学者使用range函数迭代大量元素,内存和CPU效率都很低;但他们忽略了使用 range 函数生成数字列表。现在,他们已经改变了,已经太迟了。

    如果我要成为 Python3 的设计者,我会:

    1. 使用 irange 返回一个序列迭代器
    2. 使用 lrange 返回一个序列列表
    3. 使用 range 返回序列迭代器(如果元素数量很大,例如 range(9999999) 或序列列表(如果元素数量很小,例如 range(10))

    这应该是最佳的。

    【讨论】:

    • 这如何回答这个问题?
    • 是的,它通过要求 Python3 开发人员更改和改进 Python3 来回答这个问题。但它们不太可能改变,因为它们并不那么优雅。
    【解决方案7】:

    在 Python 3 中使用 Range

    这是一个在两个数字之间返回数字的示例函数

    def get_between_numbers(a, b):
        """
        This function will return in between numbers from two numbers.
        :param a:
        :param b:
        :return:
        """
        x = []
        if b < a:
            x.extend(range(b, a))
            x.append(a)
        else:
            x.extend(range(a, b))
            x.append(b)
    
        return x
    

    结果

    print(get_between_numbers(5, 9))
    print(get_between_numbers(9, 5))
    
    [5, 6, 7, 8, 9]  
    [5, 6, 7, 8, 9]
    

    【讨论】:

    • 这似乎是在回答一个不同的问题...?
    【解决方案8】:

    Python3 之所以缺少直接获取范围列表的功能,是因为最初的 Python3 设计者在 Python2 中相当新手。他只考虑在 for 循环中使用range() 函数,因此,列表永远不需要扩展。事实上,我们经常需要使用range() 函数来生成列表并传递给函数。

    因此,在这种情况下,Python3 不如 Python2 方便,因为:

    • 在Python2中,我们有xrange()range()
    • 在 Python3 中,我们有 range()list(range())

    尽管如此,您仍然可以通过这种方式使用列表扩展:

    [*range(N)]
    

    【讨论】:

    • 整个要点是为了让创建list 变得不那么方便,因为这通常是错误的做法。对于 100 个用例中的 99 个,创建一个实际的 list 效率低下且毫无意义,因为 range 本身在几乎所有方面都像一个不可变的序列,有时启动效率更高(例如,ints 的包含测试是 @ 987654332@,与O(n) 相比,lists)。在 Python 2 中,人们倾向于默认使用 range,尽管 xrange 几乎总是更好的选择;在 Python 3 中,您可以明确选择加入 list,而不是通过使用错误的名称意外获得它。
    • 关于 Python 3 设计师和他在 Python 2 方面的专长的评论相当大胆和无礼。
    • @kazarey 但这是真的吗? python 中有很多东西在这些方面是有问题的
    • 会赞成,特别是对于构造列表的拆包速记,但我同意@kazarey。关于设计师的评论既没有根据(或至少没有参考依据)也没有必要。
    【解决方案9】:

    Python 3:

    my_list = [*range(1001)]
    

    【讨论】:

      猜你喜欢
      • 2011-06-05
      • 2020-01-21
      • 1970-01-01
      • 2017-10-02
      • 1970-01-01
      • 2016-07-05
      • 2018-10-25
      • 2019-07-27
      • 1970-01-01
      相关资源
      最近更新 更多