scala> val two = (1,2)
two: (Int, Int) = (1,2)
scala> val one = (1,)
<console>:1: error: illegal start of simple expression
val one = (1,)
^
scala> val zero = ()
zero: Unit = ()
Run Code Online (Sandbox Code Playgroud)
这是:
val one = Tuple1(5)
Run Code Online (Sandbox Code Playgroud)
在Scala中编写单例元组文字真的是最简洁的方法吗?并且Unit
像空元组一样工作吗?
这种不一致是否会困扰其他人?
我正在创建一个被另一个函数占用的生成器,但我仍然想知道生成了多少项:
lines = (line.rstrip('\n') for line in sys.stdin)
process(lines)
print("Processed {} lines.".format( ? ))
Run Code Online (Sandbox Code Playgroud)
我能想到的最好的方法是用一个保持计数的类来包装发生器,或者可以将其内部转出并发送()内容.是否有一种优雅而有效的方法来查看当你生成多少项时发生器不是在Python 2中使用它的人吗?
编辑:这是我最终得到的:
class Count(Iterable):
"""Wrap an iterable (typically a generator) and provide a ``count``
field counting the number of items.
Accessing the ``count`` field before iteration is finished will
invalidate the count.
"""
def __init__(self, iterable):
self._iterable = iterable
self._counter = itertools.count()
def __iter__(self):
return itertools.imap(operator.itemgetter(0), itertools.izip(self._iterable, self._counter))
@property
def count(self):
self._counter = itertools.repeat(self._counter.next())
return self._counter.next()
Run Code Online (Sandbox Code Playgroud) 我有一些文件看起来像:
/path/with spaces/{a,b,c}/*.gz
Run Code Online (Sandbox Code Playgroud)
我需要在a,b,c
dirs 子集下匹配glob的所有文件最终作为单个命令的参数:
mycmd '/path/with spaces/a/1.gz' '/path/with spaces/a/2.gz' '/path/with spaces/c/3.gz' ...
Run Code Online (Sandbox Code Playgroud)
我关心的目录作为命令行参数进入,我将它们放在一个数组中:
dirs=( "$@" )
Run Code Online (Sandbox Code Playgroud)
我想做的事情如下:
IFS=,
mycmd "/path/with spaces/{${dirs[*]}}/"*.gz
Run Code Online (Sandbox Code Playgroud)
但这不起作用,因为bash在变量之前扩展括号.我曾尝试过使用echo
和ls
甚至eval
(*shudder*)的技巧,但很难让它们与文件名中的空格一起使用. find
似乎没有多大帮助,因为它没有做括号.我可以为数组中的每个目录获取一个单独的glob:
dirs=( "${dirs[@]/#//path/with spaces/}" )
dirs=( "${dirs[@]/%//*.gz}" )
Run Code Online (Sandbox Code Playgroud)
但随后bash在扩展时引用了通配符.
那么:是否有一种优雅的方法可以使所有文件与变量括号和glob模式匹配,正确处理空间,还是我坚持做循环?如果这有所作为,我正在使用Bash 3.
我正在尝试使用Java将大型文本语料库读入内存.在某些时候,它撞到墙壁,只是垃圾无休止地收集.我想知道是否有人有经验将Java的GC用于提交大型数据集.
我正在读一个8 GB的英文文本文件,用UTF-8,一行写一行.我希望split()
在空格上的每一行,并将结果的String数组存储在一个ArrayList<String[]>
进行进一步处理.这是一个展示问题的简化程序:
/** Load whitespace-delimited tokens from stdin into memory. */
public class LoadTokens {
private static final int INITIAL_SENTENCES = 66000000;
public static void main(String[] args) throws IOException {
List<String[]> sentences = new ArrayList<String[]>(INITIAL_SENTENCES);
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
long numTokens = 0;
String line;
while ((line = stdin.readLine()) != null) {
String[] sentence = line.split("\\s+");
if (sentence.length > 0) {
sentences.add(sentence);
numTokens += sentence.length;
}
}
System.out.println("Read " + sentences.size() + " …
Run Code Online (Sandbox Code Playgroud) 由于==
不能使用Arrays,我无法有效地创建一组数组(或使用数组键映射).我宁愿不把我的数组转换为Vector或List或其他东西.有没有一种轻量级的方法来定义Arrays上的自然比较和哈希码,所以我可以将它们粘贴在一个Set中?
我希望能够在Scala中使用JUnit 4.7的ExpectedException @Rule.但是,似乎没有任何东西:
import org.junit._
class ExceptionsHappen {
@Rule
def thrown = rules.ExpectedException.none
@Test
def badInt: Unit = {
thrown.expect(classOf[NumberFormatException])
Integer.parseInt("one")
}
}
Run Code Online (Sandbox Code Playgroud)
这仍然失败了NumberFormatException
.
我有CSV文件,其中包含列名称的注释,其中列在整个文件中发生变化:
#c1,c2,c3
a,b,c
d,e,f
#c4,c5
g,h
i,j
Run Code Online (Sandbox Code Playgroud)
我想提供一种方法来迭代(仅)文件的数据行作为列名称映射到值(所有字符串).所以上面会变成:
Map(c1 -> a, c2 -> b, c3 -> c)
Map(c1 -> d, c2 -> e, c3 -> f)
Map(c4 -> g, c5 -> h)
Map(c4 -> i, c5 -> j)
Run Code Online (Sandbox Code Playgroud)
文件非常大,因此无法将所有内容读入内存.现在我有一个Iterator
班级,在hasNext()
和之间保持一些丑陋的状态next()
; 我还提供当前行号的访问器和实际的最后一行和注释读取(如果消费者关心字段顺序).我想尝试以更实用的方式做事.
我的第一个想法是理解:我可以迭代文件的行,用过滤子句跳过注释行.我可以yield
使用包含地图,行号等的元组.问题是我需要记住最后看到的列名,以便我可以从中创建地图.对于循环可以理解,试图阻止保持状态,只允许你设置新val
的.我从中学到了这个问题,我可以更新成员变量yield
块,而这正是我不希望在我的情况进行更新!
我可以在迭代子句中调用一个更新状态的函数,但这看起来很脏.那么,在功能风格中执行此操作的最佳方法是什么?滥用理解?哈克scanLeft?使用图书馆?带出解析器组合大枪吗?或者功能性风格是不是很适合这个问题?
我有非常大的迭代器,我想分成几块.我有一个查看项目的谓词,如果它是新作品的开头,则返回true.我需要将这些碎片作为迭代器,因为即使碎片也不适合记忆.有很多部分,我会担心一个递归的解决方案吹出你的堆栈.情况类似于这个问题,但我需要Iterators而不是Lists,并且"sentinels"(谓词为true的项目)在一个片段的开头出现(并且应该包括在内).生成的迭代器将仅按顺序使用,但有些可能根本不使用,它们应该只使用O(1)内存.我想这意味着它们应该共享相同的底层迭代器.表现很重要.
如果我要对函数签名进行攻击,那就是:
def groupby[T](iter: Iterator[T])(startsGroup: T => Boolean): Iterator[Iterator[T]] = ...
Run Code Online (Sandbox Code Playgroud)
我会喜欢使用takeWhile
它,但它失去了最后一个元素.我调查了span
,但它缓冲了结果.我当前最好的想法涉及BufferedIterator
,但也许有更好的方法.
你会知道你做得对,因为这样的事情不会让你的JVM崩溃:
groupby((1 to Int.MaxValue).iterator)(_ % (Int.MaxValue / 2) == 0).foreach(group => println(group.sum))
groupby((1 to Int.MaxValue).iterator)(_ % 10 == 0).foreach(group => println(group.sum))
Run Code Online (Sandbox Code Playgroud) 在Scala 2.9.1中,这很好用:
scala> (1 to Int.MaxValue).sum
res6: Int = -1073741824
Run Code Online (Sandbox Code Playgroud)
但是这会耗尽堆空间:
scala> (1 to Int.MaxValue).toIterator.sum
java.lang.OutOfMemoryError: GC overhead limit exceeded
Run Code Online (Sandbox Code Playgroud)
但令人抓狂的是,这有效:
scala> (1 to Int.MaxValue).iterator.sum
res8: Int = -1073741824
Run Code Online (Sandbox Code Playgroud)
为什么这些会有所不同?