Python或Bash将文本文件中的所有单词迭代到

2024-10-06 11:22:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含数千个单词的文本文件,例如:

laban
labrador
labradors
lacey
lachesis
lacy
ladoga
ladonna
lafayette
lafitte
lagos
lagrange
lagrangian
lahore
laius
lajos
lakeisha
lakewood

我想把每一个词都重复一遍,这样我就能得到:

^{pr2}$

在bash中,我可以执行以下操作,但速度非常慢:

^{3}$

有没有更快更有效的方法? 另外,如何以这种方式迭代两个不同的文本文件?在


Tags: 单词文本文件laceylagrangelabradorlagrangianlagoslabradors
3条回答

看起来sed在每一行追加一个文本是非常有效的。 我提议:

#!/bin/bash

for word in $(< words.txt)
do 
    sed "s/$/$word/" words.txt;
done > doublewords.txt

(您是否混淆了$,这意味着sed的行尾,而{}是bash变量)。在

对于一个2000行的文件,在我的计算机上运行大约20秒,而您的解决方案大约需要2分钟。在


备注:看起来你最好重定向整个程序的标准输出,而不是在每个循环中强制写入。在


(警告,这有点离题和个人观点!)在

<>如果你真的要追求速度,你应该考虑使用编译的语言,如C++。例如:

^{pr2}$

您需要了解bash和python都不擅长double for循环:这就是为什么要使用技巧(@Thanatos)或预定义命令(sed)。最近,我遇到了一个双循环问题(给定一组10000个点的3D,计算所有的距离对),我成功地用C++来代替它,而不是Python或Matlab。在

如果您可以将列表放入内存:

import itertools

with open(words_filename, 'r') as words_file:
    words = [word.strip() for word in words_file]

for words in itertools.product(words, repeat=2):
    print(''.join(words))

(你也可以做双for循环,但我今晚感觉itertools。)

我怀疑这里的成功之处在于我们可以避免反复读取文件;bash示例中的内部循环将在外部循环的每次迭代中对该文件进行一次搜索。另外,我认为Python的执行速度比bash快,IIRC。在

当然可以用bash实现这个技巧(将文件读入一个数组,编写一个double for循环),这只会更痛苦。在

如果你有GHC可用,笛卡尔产品是一个同步!在

Q1:一个文件

-- words.hs
import Control.Applicative
main = interact f
    where f = unlines . g . words
          g x = map (++) x <*> x

{1>然后将每个单词的列表附加到每个单词的列表中。在

用GHC编译

^{pr2}$

然后使用IO重定向运行:

./words <words.txt >out

Q2:两个文件

-- words2.hs
import Control.Applicative
import Control.Monad
import System.Environment
main = do
    ws <- mapM ((liftM words) . readFile) =<< getArgs
    putStrLn $ unlines $ g ws
    where g (x:y:_) = map (++) x <*> y

像以前一样编译并以两个文件作为参数运行:

./words2 words1.txt words2.txt > out

Bleh,编译?

想要shell脚本的便利性和编译后的可执行文件的性能吗?为什么不同时做呢?在

只需将所需的Haskell程序包装在包装器脚本中,该脚本在/var/tmp中编译该程序,然后将其自身替换为生成的可执行文件:

#!/bin/bash
# wrapper.sh

cd /var/tmp
cat > c.hs <<CODE
# replace this comment with haskell code
CODE
ghc c.hs >/dev/null
cd - >/dev/null
exec /var/tmp/c "$@"

它处理参数和IO重定向,就像包装器不存在一样。在

结果

用两个2000字的文件对照其他答案计时:

$ time ./words2 words1.txt words2.txt >out
3.75s user 0.20s system 98% cpu 4.026 total

$ time ./wrapper.sh words1.txt words2.txt > words2
4.12s user 0.26s system 97% cpu 4.485 total

$ time ./thanatos.py > out
4.93s user 0.11s system 98% cpu 5.124 total

$ time ./styko.sh
7.91s user 0.96s system 74% cpu 11.883 total

$ time ./user3552978.sh
57.16s user 29.17s system 93% cpu 1:31.97 total

相关问题 更多 >