我有来自Python的这段代码将csv(逗号分隔的文本值)文件逐行读取为字符串,然后将每个这样的行字符串拆分为字段并在控制台上打印:
def readfilefn(filename):
with open(filename,"r") as f:
for line in f:
flds = line.split(',')
for fld in flds:
print fld.strip()
我正在尝试将其转换为Lisp代码。我在How can I read the contents of a file into a list in Lisp?上找到了以下代码:
(defun get-file (filename)
(with-open-file (stream filename)
(loop for line = (read-line stream nil)
while line
collect line)))
和一个来自:https://groups.google.com/forum/#!topic/comp.lang.lisp/r8O6Py8E1zE
(defun read-all-lines (input-stream)
(do ((line nil)
(result nil (cons line result)))
((eq line :eof) (nreverse result))
(setq line (read-line input-stream nil :eof))))
(这里的线必须使用nreverse反转)。
将整行字符串拆分为字段字符串:https://gist.github.com/siguremon/1174988
(defun split-str (string &optional (separator " "))
(split-str-1 string separator))
(defun split-str-1 (string &optional (separator " ") (r nil))
(let ((n (position separator string
:from-end t
:test #'(lambda (x y)
(find y x :test #'string=)))))
(if n
(split-str-1 (subseq string 0 n) separator (cons (subseq string (1+ n)) r))
(cons string r))))
还有许多其他例程可用,例如http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/need-a-lisp-routine-to-string-split/td-p/2618387
我想知道这些是安全的方法还是最好的方法。我在Linux上使用clisp(Common Lisp)。感谢您的意见/解答。
答案 0 :(得分:3)
抱歉有点迟了,正如jkilky的评论中所建议的那样,我将使用常见的lisp库cl-csv,它可以通过quicklisp获得。
CL-USER> (ql:quickload :cl-csv)
To load "cl-csv":
Load 1 ASDF system:
cl-csv
; Loading "cl-csv"
...
(:CL-CSV)
cl-csv将文件拆分为列表列表,让我们使用来自here的csv文件,名为train.csv是一个普通的csv文件:
PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
1,0,3,"Braund, Mr. Owen Harris",male,22,1,0,A/5 21171,7.25,,S
2,1,1,"Cumings, Mrs. John Bradley (Florence Briggs Thayer)",female,38,1,0,PC 17599,71.2833,C85,C
3,1,3,"Heikkinen, Miss. Laina",female,26,0,0,STON/O2. 3101282,7.925,,S
4,1,1,"Futrelle, Mrs. Jacques Heath (Lily May Peel)",female,35,1,0,113803,53.1,C123,S
5,0,3,"Allen, Mr. William Henry",male,35,0,0,373450,8.05,,S
6,0,3,"Moran, Mr. James",male,,0,0,330877,8.4583,,Q
7,0,1,"McCarthy, Mr. Timothy J",male,54,0,0,17463,51.8625,E46,S
8,0,3,"Palsson, Master. Gosta Leonard",male,2,3,1,349909,21.075,,S
9,1,3,"Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)",female,27,0,2,347742,11.1333,,S
10,1,2,"Nasser, Mrs. Nicholas (Adele Achem)",female,14,1,0,237736,30.0708,,C
11,1,3,"Sandstrom, Miss. Marguerite Rut",female,4,1,1,PP 9549,16.7,G6,S
12,1,1,"Bonnell, Miss. Elizabeth",female,58,0,0,113783,26.55,C103,S
13,0,3,"Saundercock, Mr. William Henry",male,20,0,0,A/5. 2151,8.05,,S
...
...
Cl-csv将其加载到列表中,每行都是一个列表:
CL-USER> (cl-csv:read-csv #P"./train.csv")
(("PassengerId" "Survived" "Pclass" "Name" "Sex" "Age" "SibSp" "Parch" "Ticket"
"Fare" "Cabin" "Embarked")
("1" "0" "3" "Braund, Mr. Owen Harris" "male" "22" "1" "0" "A/5 21171" "7.25"
"" "S")
("2" "1" "1" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "female"
"38" "1" "0" "PC 17599" "71.2833" "C85" "C")
("3" "1" "3" "Heikkinen, Miss. Laina" "female" "26" "0" "0" "STON/O2. 3101282"
"7.925" "" "S")
("4" "1" "1" "Futrelle, Mrs. Jacques Heath (Lily May Peel)" "female" "35" "1"
"0" "113803" "53.1" "C123" "S")
("5" "0" "3" "Allen, Mr. William Henry" "male" "35" "0" "0" "373450" "8.05" ""
"S")
("6" "0" "3" "Moran, Mr. James" "male" "" "0" "0" "330877" "8.4583" "" "Q")
("7" "0" "1" "McCarthy, Mr. Timothy J" "male" "54" "0" "0" "17463" "51.8625"
"E46" "S")
("8" "0" "3" "Palsson, Master. Gosta Leonard" "male" "2" "3" "1" "349909"
"21.075" "" "S")
然后打印它只是使用格式功能,这是打印列表和每个列表的分隔符的一个小技巧,我使用nil而不是t来获取字符串,但你可以用t打印它,所以这是在lisp中得到这个的单行程序,我使用新行分隔符表示第一级列表(然后是行),然后使用“,”表示行的项目:
CL-USER> (format nil "~{~{~a, ~}~% ~}" (cl-csv:read-csv #P"train.csv"))
"PassengerId, Survived, Pclass, Name, Sex, Age, SibSp, Parch, Ticket, Fare, Cabin, Embarked,
1, 0, 3, Braund, Mr. Owen Harris, male, 22, 1, 0, A/5 21171, 7.25, , S,
2, 1, 1, Cumings, Mrs. John Bradley (Florence Briggs Thayer), female, 38, 1, 0, PC 17599, 71.2833, C85, C,
3, 1, 3, Heikkinen, Miss. Laina, female, 26, 0, 0, STON/O2. 3101282, 7.925, , S,
4, 1, 1, Futrelle, Mrs. Jacques Heath (Lily May Peel), female, 35, 1, 0, 113803, 53.1, C123, S,
5, 0, 3, Allen, Mr. William Henry, male, 35, 0, 0, 373450, 8.05, , S,
6, 0, 3, Moran, Mr. James, male, , 0, 0, 330877, 8.4583, , Q,
7, 0, 1, McCarthy, Mr. Timothy J, male, 54, 0, 0, 17463, 51.8625, E46, S,
8, 0, 3, Palsson, Master. Gosta Leonard, male, 2, 3, 1, 349909, 21.075, , S,
9, 1, 3, Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg), female, 27, 0, 2, 347742, 11.1333, , S,
10, 1, 2, Nasser, Mrs. Nicholas (Adele Achem), female, 14, 1, 0, 237736, 30.0708, , C,
11, 1, 3, Sandstrom, Miss. Marguerite Rut, female, 4, 1, 1, PP 9549, 16.7, G6, S,
12, 1, 1, Bonnell, Miss. Elizabeth, female, 58, 0, 0, 113783, 26.55, C103, S,
13, 0, 3, Saundercock, Mr. William Henry, male, 20, 0, 0, A/5. 2151, 8.05, , S,
14, 0, 3, Andersson, Mr. Anders Johan, male, 39, 1, 5, 347082, 31.275, , S,
15, 0, 3, Vestrom, Miss. Hulda Amanda Adolfina, female, 14, 0, 0, 350406, 7.8542, , S,
16, 1, 2, Hewlett, Mrs. (Mary D Kingcome) , female, 55, 0, 0, 248706, 16, , S,
17, 0, 3, Rice, Master. Eugene, male, 2, 4, 1, 382652, 29.125, , Q,
18, 1, 2, Williams, Mr. Charles Eugene, male, , 0, 0, 244373, 13, , S,
19, 0, 3, Vander Planke, Mrs. Julius (Emelia Maria Vandemoortele), female, 31, 1, 0, 345763, 18, , S,
我希望这有助于