我认为这Iterator.copy()将是一个非常方便的功能.您可以以更好的方式实现迭代器过滤器.
例如,Googles Java Collection中filter(和类似的)函数使用的唯一原因UnmodifiableIterator(只是Iterator没有remove)是因为你不能实现这样的过滤器,Iterator否则无法在某些时候复制它.(真的,使用当前界面是不可能的;试试吧.)
另一个优点是你可以在for-each-loop中使用迭代器:因为可复制的迭代器也可以自动迭代.另见这个问题.目前,主要的设计理由不允许这样做是因为Iterator它实现Iterable并Iterator<T> iterator() { return this; }会使无效迭代器.通过使用一个copy函数,它就像它一样简单Iterator<T> iterator() { return copy(); }并且它不会使原始迭代器无效.因此,没有理由不允许这样做.
有什么缘故吗?只是为了减少实现它的复杂性?
是否有一个简单的方法来检查元素是否包含在迭代或迭代器中,类似于Collection.contains(Object o)方法?
即不必写:
Iterable<String> data = getData();
for (final String name : data) {
if (name.equals(myName)) {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
我想写:
Iterable<String> data = getData();
if (Collections.contains(data, myName)) {
return true;
}
Run Code Online (Sandbox Code Playgroud)
我真的很惊讶没有这样的事情.
我有一个包含私有可变数据列表的类.
我需要在以下条件下公开列表项:
应该将哪个getter函数标记为推荐方法?或者你能提供更好的解决方案吗?
class DataProcessor {
private final ArrayList<String> simpleData = new ArrayList<>();
private final CopyOnWriteArrayList<String> copyData = new CopyOnWriteArrayList<>();
public void modifyData() {
...
}
public Iterable<String> getUnmodifiableIterable() {
return Collections.unmodifiableCollection(simpleData);
}
public Iterator<String> getUnmodifiableIterator() {
return Collections.unmodifiableCollection(simpleData).iterator();
}
public Iterable<String> getCopyIterable() {
return copyData;
}
public Iterator<String> getCopyIterator() {
return copyData.iterator();
}
}
Run Code Online (Sandbox Code Playgroud)
UPD:这个问题来自关于列表getter实现的最佳实践的真实代码审查讨论
我试图找到一种优雅的方法来找到二维数组中的最大值.例如对于这个数组:
[0, 0, 1, 0, 0, 1] [0, 1, 0, 2, 0, 0][0, 0, 2, 0, 0, 1][0, 1, 0, 3, 0, 0][0, 0, 0, 0, 4, 0]
Run Code Online (Sandbox Code Playgroud)
我想提取值'4'.我想在最大范围内做一个最大值,但我正在努力执行它.
从python3到Julia,人们希望能够将快速迭代器编写为具有yield/yield语法的函数或类似的东西.
Julia的宏似乎暗示可以构建一个宏,将这种"生成器"函数转换为julia迭代器.[它甚至看起来你可以很容易地内联函数风格的迭代器,这是Iterators.jl包也尝试为其特定的迭代器提供的功能https://github.com/JuliaCollections/Iterators.jl#the-itr- macro-for-automatic-inlining-in-for-loops ]
只是举个例子来说明我的想法:
@asiterator function myiterator(as::Array)
b = 1
for (a1, a2) in zip(as, as[2:end])
try
@produce a1[1] + a2[2] + b
catch exc
end
end
end
for i in myiterator([(1,2), (3,1), 3, 4, (1,1)])
@show i
end
Run Code Online (Sandbox Code Playgroud)
myiterator理想情况下应该在哪里创建一个尽可能低开销的快速迭代器.当然,这只是一个具体的例子.理想情况下,我想拥有适用于所有或几乎所有发电机功能的东西.
目前推荐的将生成器函数转换为迭代器的方法是通过Julia的任务,至少据我所知.然而,它们似乎也比纯粹的迭代器慢.例如,如果你可以用简单的迭代器表示你的函数imap,chain等等(由Iterators.jl包提供),这似乎是非常可取的.
在julia理论上是否有可能将生成器类型的宏转换为灵活的快速迭代器?
额外问题:如果可能的话,是否有一个通用宏可以内联这样的迭代器?
我在研究 For/in 和 For/of 循环时遇到术语 Iterable 和 Enumerable。对象应该是可枚举的,我们必须使用 For/in 循环来循环对象的属性,并使用 For/of 来循环数组和字符串。我无法理解这两个术语。这两者有什么区别?
我知道Scala的列表有一个带签名的map实现和带签名(f: (A) => B):List[B]的foreach实现,(f: (A) => Unit):Unit但我正在寻找接受多个iterables的东西,就像Python map接受多个iterables一样.
我正在寻找具有特征(f: (A,B) => C, Iterable[A], Iterable[B] ):Iterable[C]或同等特征的东西.是否存在存在这样的库或类似的类似方法?
编辑:
如下所示,我可以做到
val output = myList zip( otherList ) map( x => x(0) + x(1) )
Run Code Online (Sandbox Code Playgroud)
但这会在两个步骤之间创建一个临时列表.如果评论员会发帖,我可以赞成他(提示,提示),但还有另一种方式吗?
如果我__iter__按如下方式定义方法,它将无法工作:
class A:
def __init__(self):
self.__iter__ = lambda: iter('text')
for i in A().__iter__():
print(i)
iter(A())
Run Code Online (Sandbox Code Playgroud)
结果:
t
e
x
t
Traceback (most recent call last):
File "...\mytest.py", line 10, in <module>
iter(A())
TypeError: 'A' object is not iterable
Run Code Online (Sandbox Code Playgroud)
如您所见,调用A().__iter__()工作,但A()不可迭代.
但是,如果我__iter__为类定义,那么它将工作:
class A:
def __init__(self):
self.__class__.__iter__ = staticmethod(lambda: iter('text'))
# or:
# self.__class__.__iter__ = lambda s: iter('text')
for i in A():
print(i)
iter(A())
# will print:
# t
# e
# x
# …Run Code Online (Sandbox Code Playgroud) 我的函数foo接受一个things在内部变成列表的参数。
def foo(things):
things = list(things)
# more code
Run Code Online (Sandbox Code Playgroud)
该list构造函数接受任何可迭代。
但是,注释thingswithtyping.Iterable并没有给用户一个线索,即迭代必须是有限的,而不是像itertools.count().
在这种情况下使用的正确类型提示是什么?
我正在处理一些需要不断从迭代中获取元素的代码,只要基于(或与之相关)前一个元素的条件为真。例如,假设我有一个数字列表:
lst = [0.1, 0.4, 0.2, 0.8, 0.7, 1.1, 2.2, 4.1, 4.9, 5.2, 4.3, 3.2]
Run Code Online (Sandbox Code Playgroud)
让我们使用一个简单的条件:该数字与前一个数字的差异不超过 1。因此预期输出将是
[0.1, 0.4, 0.2, 0.8, 0.7, 1.1]
Run Code Online (Sandbox Code Playgroud)
通常,itertools.takewhile这是一个不错的选择,但在这种情况下它有点烦人,因为第一个元素没有要查询的前一个元素。以下代码返回一个空列表,因为对于第一个元素,代码会查询最后一个元素。
from itertools import takewhile
res1 = list(takewhile(lambda x: abs(lst[lst.index(x)-1] - x) <= 1., lst))
print(res1)
# []
Run Code Online (Sandbox Code Playgroud)
我设法编写了一些“丑陋”的代码来解决:
res2 = []
for i, x in enumerate(lst):
res2.append(x)
# Make sure index is not out of range
if i < len(lst) - 1:
if not abs(lst[i+1] - x) <= 1.:
break
print(res2)
# [0.1, 0.4, …Run Code Online (Sandbox Code Playgroud) iterable ×10
iterator ×4
python ×4
java ×3
python-3.x ×2
applicative ×1
arraylist ×1
arrays ×1
collections ×1
copy ×1
enumerable ×1
for-in-loop ×1
for-of-loop ×1
iteration ×1
javascript ×1
julia ×1
list ×1
max ×1
scala ×1
type-hinting ×1